<!DOCTYPE html><html class=split lang=en-US-x-hixie><script src=../link-fixup.js defer=""></script>
<!-- Mirrored from html.spec.whatwg.org/multipage/workers.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 10 Sep 2025 08:35:54 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<meta charset=utf-8><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name=viewport><title>HTML Standard</title><meta content=#3c790a name=theme-color><meta content="light dark" name=color-scheme><link rel=stylesheet href=../../resources.whatwg.org/standard-shared-with-dev.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/standard.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/spec.css crossorigin=""><link rel=icon href=https://resources.whatwg.org/logo.svg crossorigin=""><link rel=stylesheet href=../styles.css crossorigin=""><script>
   function toggleStatus(div) {
     div.parentNode.classList.toggle('wrapped');
   }
   function setLinkFragment(link) {
     link.hash = location.hash;
   }
  </script><body>
  
  <script defer="" crossorigin="" src=../html-dfn.js></script>
  
  <header id=head class="head with-buttons">
   <a href=https://whatwg.org/ class=logo><img width=100 alt=WHATWG crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/logo.svg height=100></a>
   <hgroup><h1 class=allcaps>HTML</h1><p id=living-standard>Living Standard — Last Updated <span class=pubdate>10 September 2025</span></hgroup>
   
   

   
  </header>

  

  

  

  
  

  
  

  

  <nav><a href=web-messaging.html>← 9.3 Cross-document messaging</a> — <a href=index.html>Table of Contents</a> — <a href=worklets.html>11 Worklets →</a></nav><ol class=toc><li id=toc-workers><a href=workers.html#workers><span class=secno>10</span> Web workers</a><ol><li><a href=workers.html#introduction-14><span class=secno>10.1</span> Introduction</a><ol><li><a href=workers.html#scope-2><span class=secno>10.1.1</span> Scope</a><li><a href=workers.html#examples-6><span class=secno>10.1.2</span> Examples</a><ol><li><a href=workers.html#a-background-number-crunching-worker><span class=secno>10.1.2.1</span> A background number-crunching worker</a><li><a href=workers.html#module-worker-example><span class=secno>10.1.2.2</span> Using a JavaScript module as a worker</a><li><a href=workers.html#shared-workers-introduction><span class=secno>10.1.2.3</span> Shared workers introduction</a><li><a href=workers.html#shared-state-using-a-shared-worker><span class=secno>10.1.2.4</span> Shared state using a shared worker</a><li><a href=workers.html#delegation><span class=secno>10.1.2.5</span> Delegation</a><li><a href=workers.html#providing-libraries><span class=secno>10.1.2.6</span> Providing libraries</a></ol><li><a href=workers.html#tutorials><span class=secno>10.1.3</span> Tutorials</a><ol><li><a href=workers.html#creating-a-dedicated-worker><span class=secno>10.1.3.1</span> Creating a dedicated worker</a><li><a href=workers.html#communicating-with-a-dedicated-worker><span class=secno>10.1.3.2</span> Communicating with a dedicated worker</a><li><a href=workers.html#shared-workers><span class=secno>10.1.3.3</span> Shared workers</a></ol></ol><li><a href=workers.html#infrastructure-2><span class=secno>10.2</span> Infrastructure</a><ol><li><a href=workers.html#the-global-scope><span class=secno>10.2.1</span> The global scope</a><ol><li><a href=workers.html#the-workerglobalscope-common-interface><span class=secno>10.2.1.1</span> The <code>WorkerGlobalScope</code> common interface</a><li><a href=workers.html#dedicated-workers-and-the-dedicatedworkerglobalscope-interface><span class=secno>10.2.1.2</span> Dedicated workers and the <code>DedicatedWorkerGlobalScope</code> interface</a><li><a href=workers.html#shared-workers-and-the-sharedworkerglobalscope-interface><span class=secno>10.2.1.3</span> Shared workers and the <code>SharedWorkerGlobalScope</code> interface</a></ol><li><a href=workers.html#worker-event-loop><span class=secno>10.2.2</span> The event loop</a><li><a href="workers.html#the-worker's-lifetime"><span class=secno>10.2.3</span> The worker's lifetime</a><li><a href=workers.html#worker-processing-model><span class=secno>10.2.4</span> Processing model</a><li><a href=workers.html#runtime-script-errors-2><span class=secno>10.2.5</span> Runtime script errors</a><li><a href=workers.html#creating-workers><span class=secno>10.2.6</span> Creating workers</a><ol><li><a href=workers.html#the-abstractworker-mixin><span class=secno>10.2.6.1</span> The
  <code>AbstractWorker</code> mixin</a><li><a href=workers.html#script-settings-for-workers><span class=secno>10.2.6.2</span> Script settings for workers</a><li><a href=workers.html#dedicated-workers-and-the-worker-interface><span class=secno>10.2.6.3</span> Dedicated workers and the <code>Worker</code> interface</a><li><a href=workers.html#shared-workers-and-the-sharedworker-interface><span class=secno>10.2.6.4</span> Shared workers and the <code>SharedWorker</code> interface</a></ol><li><a href=workers.html#navigator.hardwareconcurrency><span class=secno>10.2.7</span> Concurrent hardware capabilities</a></ol><li><a href=workers.html#apis-available-to-workers><span class=secno>10.3</span> APIs available to workers</a><ol><li><a href=workers.html#importing-scripts-and-libraries><span class=secno>10.3.1</span> Importing scripts and libraries</a><li><a href=workers.html#the-workernavigator-object><span class=secno>10.3.2</span> The <code>WorkerNavigator</code> interface</a><li><a href=workers.html#worker-locations><span class=secno>10.3.3</span> The <code>WorkerLocation</code> interface</a></ol></ol></ol><h2 id=workers data-dfn-type=dfn data-lt="web worker" data-export=""><span class=secno>10</span> Web workers<a href=#workers class=self-link></a></h2><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API title="Web Workers makes it possible to run a script operation in a background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down.">Web_Workers_API</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers title="Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are always null) or fetch (with no such restrictions). Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).">Web_Workers_API/Using_web_workers</a></div></div>

  <h3 id=introduction-14><span class=secno>10.1</span> Introduction<a href=#introduction-14 class=self-link></a></h3>

  <h4 id=scope-2><span class=secno>10.1.1</span> Scope<a href=#scope-2 class=self-link></a></h4>

  <p><i>This section is non-normative.</i></p>

  <p>This specification defines an API for running scripts in the background independently of any
  user interface scripts.</p>

  <p>This allows for long-running scripts that are not interrupted by scripts that respond to clicks
  or other user interactions, and allows long tasks to be executed without yielding to keep the page
  responsive.</p>

  <p>Workers (as these background scripts are called herein) are relatively heavy-weight, and are
  not intended to be used in large numbers. For example, it would be inappropriate to launch one
  worker for each pixel of a four megapixel image. The examples below show some appropriate uses of
  workers.</p>

  <p>Generally, workers are expected to be long-lived, have a high start-up performance cost, and a
  high per-instance memory cost.</p>


  <h4 id=examples-6><span class=secno>10.1.2</span> Examples<a href=#examples-6 class=self-link></a></h4>

  <p><i>This section is non-normative.</i></p>

  <p>There are a variety of uses that workers can be put to. The following subsections show various
  examples of this use.</p>


  <h5 id=a-background-number-crunching-worker><span class=secno>10.1.2.1</span> A background number-crunching worker<a href=#a-background-number-crunching-worker class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>The simplest use of workers is for performing a computationally
  expensive task without interrupting the user interface.</p>

  <p>In this example, the main document spawns a worker to (naïvely) compute prime numbers, and
  progressively displays the most recently found prime number.</p>

  <p>The main page is as follows:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>head</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Worker example: One-core computation<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>head</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>body</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->The highest prime number discovered so far is: <c- p>&lt;</c-><c- f>output</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;result&quot;</c-><c- p>&gt;&lt;/</c-><c- f>output</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
   <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;worker.js&apos;</c-><c- p>);</c->
   worker<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
     document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;result&apos;</c-><c- p>).</c->textContent <c- o>=</c-> event<c- p>.</c->data<c- p>;</c->
   <c- p>};</c->
  <c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>body</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>html</c-><c- p>&gt;</c->
</code></pre>

  <p>The <code id=a-background-number-crunching-worker:dom-worker><a href=#dom-worker>Worker()</a></code> constructor call creates a worker and returns a
  <code id=a-background-number-crunching-worker:worker><a href=#worker>Worker</a></code> object representing that worker, which is used to communicate with the worker.
  That object's <code id=a-background-number-crunching-worker:handler-messageeventtarget-onmessage><a href=web-messaging.html#handler-messageeventtarget-onmessage>onmessage</a></code> event handler
  allows the code to receive messages from the worker.</p>

  <p>The worker itself is as follows:</p>

  <pre><code class='js'><c- a>var</c-> n <c- o>=</c-> <c- mf>1</c-><c- p>;</c->
search<c- o>:</c-> <c- k>while</c-> <c- p>(</c-><c- kc>true</c-><c- p>)</c-> <c- p>{</c->
  n <c- o>+=</c-> <c- mf>1</c-><c- p>;</c->
  <c- k>for</c-> <c- p>(</c-><c- a>var</c-> i <c- o>=</c-> <c- mf>2</c-><c- p>;</c-> i <c- o>&lt;=</c-> Math<c- p>.</c->sqrt<c- p>(</c->n<c- p>);</c-> i <c- o>+=</c-> <c- mf>1</c-><c- p>)</c->
    <c- k>if</c-> <c- p>(</c->n <c- o>%</c-> i <c- o>==</c-> <c- mf>0</c-><c- p>)</c->
     <c- k>continue</c-> search<c- p>;</c->
  <c- c1>// found a prime!</c->
  postMessage<c- p>(</c->n<c- p>);</c->
<c- p>}</c->
</code></pre>

  <p>The bulk of this code is simply an unoptimized search for a prime number. The <code id=a-background-number-crunching-worker:dom-dedicatedworkerglobalscope-postmessage><a href=#dom-dedicatedworkerglobalscope-postmessage>postMessage()</a></code> method is used to send a
  message back to the page when a prime is found.</p>

  <p><a href=../demos/workers/primes/page.html>View this example online</a>.</p>


  <h5 id=module-worker-example><span class=secno>10.1.2.2</span> Using a JavaScript module as a worker<a href=#module-worker-example class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>All of our examples so far show workers that run <a href=webappapis.html#classic-script id=module-worker-example:classic-script>classic
  scripts</a>. Workers can instead be instantiated using <a href=webappapis.html#module-script id=module-worker-example:module-script>module
  scripts</a>, which have the usual benefits: the ability to use the JavaScript
  <code>import</code> statement to import other modules; strict mode by default; and
  top-level declarations not polluting the worker's global scope.</p>

  <p>As the <code>import</code> statement is available, the <code id=module-worker-example:dom-workerglobalscope-importscripts><a href=#dom-workerglobalscope-importscripts>importScripts()</a></code> method will automatically fail
  inside module workers.</p>

  <p>In this example, the main document uses a worker to do off-main-thread image manipulation.
  It imports the filters used from another module.</p>

  <p>The main page is as follows:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE html&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Worker example: image decoding<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>label</c-><c- p>&gt;</c->
    Type an image URL to decode
    <c- p>&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>&quot;url&quot;</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;image-url&quot;</c-> <c- e>list</c-><c- o>=</c-><c- s>&quot;image-list&quot;</c-><c- p>&gt;</c->
    <c- p>&lt;</c-><c- f>datalist</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;image-list&quot;</c-><c- p>&gt;</c->
      <c- p>&lt;</c-><c- f>option</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;https://html.spec.whatwg.org/images/drawImage.png&quot;</c-><c- p>&gt;</c->
      <c- p>&lt;</c-><c- f>option</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;https://html.spec.whatwg.org/images/robots.jpeg&quot;</c-><c- p>&gt;</c->
      <c- p>&lt;</c-><c- f>option</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;https://html.spec.whatwg.org/images/arcTo2.png&quot;</c-><c- p>&gt;</c->
    <c- p>&lt;/</c-><c- f>datalist</c-><c- p>&gt;</c->
  <c- p>&lt;/</c-><c- f>label</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>p</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>label</c-><c- p>&gt;</c->
    Choose a filter to apply
    <c- p>&lt;</c-><c- f>select</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;filter&quot;</c-><c- p>&gt;</c->
      <c- p>&lt;</c-><c- f>option</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;none&quot;</c-><c- p>&gt;</c->none<c- p>&lt;/</c-><c- f>option</c-><c- p>&gt;</c->
      <c- p>&lt;</c-><c- f>option</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;grayscale&quot;</c-><c- p>&gt;</c->grayscale<c- p>&lt;/</c-><c- f>option</c-><c- p>&gt;</c->
      <c- p>&lt;</c-><c- f>option</c-> <c- e>value</c-><c- o>=</c-><c- s>&quot;brighten&quot;</c-><c- p>&gt;</c->brighten by 20%<c- p>&lt;/</c-><c- f>option</c-><c- p>&gt;</c->
    <c- p>&lt;/</c-><c- f>select</c-><c- p>&gt;</c->
  <c- p>&lt;/</c-><c- f>label</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>p</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>div</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;output&quot;</c-><c- p>&gt;&lt;/</c-><c- f>div</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>script</c-> <c- e>type</c-><c- o>=</c-><c- s>&quot;module&quot;</c-><c- p>&gt;</c->
  <c- a>const</c-> worker <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- u>&quot;worker.js&quot;</c-><c- p>,</c-> <c- p>{</c-> type<c- o>:</c-> <c- u>&quot;module&quot;</c-> <c- p>});</c->
  worker<c- p>.</c->onmessage <c- o>=</c-> receiveFromWorker<c- p>;</c->

  <c- a>const</c-> url <c- o>=</c-> document<c- p>.</c->querySelector<c- p>(</c-><c- u>&quot;#image-url&quot;</c-><c- p>);</c->
  <c- a>const</c-> filter <c- o>=</c-> document<c- p>.</c->querySelector<c- p>(</c-><c- u>&quot;#filter&quot;</c-><c- p>);</c->
  <c- a>const</c-> output <c- o>=</c-> document<c- p>.</c->querySelector<c- p>(</c-><c- u>&quot;#output&quot;</c-><c- p>);</c->

  url<c- p>.</c->oninput <c- o>=</c-> updateImage<c- p>;</c->
  filter<c- p>.</c->oninput <c- o>=</c-> sendToWorker<c- p>;</c->

  <c- a>let</c-> imageData<c- p>,</c-> context<c- p>;</c->

  <c- a>function</c-> updateImage<c- p>()</c-> <c- p>{</c->
    <c- a>const</c-> img <c- o>=</c-> <c- k>new</c-> Image<c- p>();</c->
    img<c- p>.</c->src <c- o>=</c-> url<c- p>.</c->value<c- p>;</c->

    img<c- p>.</c->onload <c- o>=</c-> <c- p>()</c-> <c- p>=&gt;</c-> <c- p>{</c->
      <c- a>const</c-> canvas <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- u>&quot;canvas&quot;</c-><c- p>);</c->
      canvas<c- p>.</c->width <c- o>=</c-> img<c- p>.</c->width<c- p>;</c->
      canvas<c- p>.</c->height <c- o>=</c-> img<c- p>.</c->height<c- p>;</c->

      context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- u>&quot;2d&quot;</c-><c- p>);</c->
      context<c- p>.</c->drawImage<c- p>(</c->img<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->
      imageData <c- o>=</c-> context<c- p>.</c->getImageData<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> canvas<c- p>.</c->width<c- p>,</c-> canvas<c- p>.</c->height<c- p>);</c->

      sendToWorker<c- p>();</c->
      output<c- p>.</c->replaceChildren<c- p>(</c->canvas<c- p>);</c->
    <c- p>};</c->
  <c- p>}</c->

  <c- a>function</c-> sendToWorker<c- p>()</c-> <c- p>{</c->
    worker<c- p>.</c->postMessage<c- p>({</c-> imageData<c- p>,</c-> filter<c- o>:</c-> filter<c- p>.</c->value <c- p>});</c->
  <c- p>}</c->

  <c- a>function</c-> receiveFromWorker<c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    context<c- p>.</c->putImageData<c- p>(</c->e<c- p>.</c->data<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>);</c->
  <c- p>}</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
</code></pre>

  <p>The worker file is then:</p>

  <pre><code class='js'><c- k>import</c-> <c- o>*</c-> <c- k>as</c-> filters <c- k>from</c-> <c- u>&quot;./filters.js&quot;</c-><c- p>;</c->

self<c- p>.</c->onmessage <c- o>=</c-> e <c- p>=&gt;</c-> <c- p>{</c->
  <c- a>const</c-> <c- p>{</c-> imageData<c- p>,</c-> filter <c- p>}</c-> <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
  filters<c- p>[</c->filter<c- p>](</c->imageData<c- p>);</c->
  self<c- p>.</c->postMessage<c- p>(</c->imageData<c- p>,</c-> <c- p>[</c->imageData<c- p>.</c->data<c- p>.</c->buffer<c- p>]);</c->
<c- p>};</c->
</code></pre>

  <p>Which imports the file <code>filters.js</code>:</p>

  <pre><code class='js'><c- k>export</c-> <c- a>function</c-> none<c- p>()</c-> <c- p>{}</c->

<c- k>export</c-> <c- a>function</c-> grayscale<c- p>({</c-> data<c- o>:</c-> d <c- p>})</c-> <c- p>{</c->
  <c- k>for</c-> <c- p>(</c-><c- a>let</c-> i <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> i <c- o>&lt;</c-> d<c- p>.</c->length<c- p>;</c-> i <c- o>+=</c-> <c- mf>4</c-><c- p>)</c-> <c- p>{</c->
    <c- a>const</c-> <c- p>[</c->r<c- p>,</c-> g<c- p>,</c-> b<c- p>]</c-> <c- o>=</c-> <c- p>[</c->d<c- p>[</c->i<c- p>],</c-> d<c- p>[</c->i <c- o>+</c-> <c- mf>1</c-><c- p>],</c-> d<c- p>[</c->i <c- o>+</c-> <c- mf>2</c-><c- p>]];</c->

    <c- c1>// CIE luminance for the RGB</c->
    <c- c1>// The human eye is bad at seeing red and blue, so we de-emphasize them.</c->
    d<c- p>[</c->i<c- p>]</c-> <c- o>=</c-> d<c- p>[</c->i <c- o>+</c-> <c- mf>1</c-><c- p>]</c-> <c- o>=</c-> d<c- p>[</c->i <c- o>+</c-> <c- mf>2</c-><c- p>]</c-> <c- o>=</c-> <c- mf>0.2126</c-> <c- o>*</c-> r <c- o>+</c-> <c- mf>0.7152</c-> <c- o>*</c-> g <c- o>+</c-> <c- mf>0.0722</c-> <c- o>*</c-> b<c- p>;</c->
  <c- p>}</c->
<c- p>};</c->

<c- k>export</c-> <c- a>function</c-> brighten<c- p>({</c-> data<c- o>:</c-> d <c- p>})</c-> <c- p>{</c->
  <c- k>for</c-> <c- p>(</c-><c- a>let</c-> i <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> i <c- o>&lt;</c-> d<c- p>.</c->length<c- p>;</c-> <c- o>++</c->i<c- p>)</c-> <c- p>{</c->
    d<c- p>[</c->i<c- p>]</c-> <c- o>*=</c-> <c- mf>1.2</c-><c- p>;</c->
  <c- p>}</c->
<c- p>};</c->
</code></pre>

  <p><a href=../demos/workers/modules/page.html>View this example online</a>.</p>


  <h5 id=shared-workers-introduction><span class=secno>10.1.2.3</span> Shared workers introduction<a href=#shared-workers-introduction class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker title="The SharedWorker interface represents a specific kind of worker that can be accessed from several browsing contexts, such as several windows, iframes or even workers. They implement an interface different than dedicated workers and have a different global scope, SharedWorkerGlobalScope.">SharedWorker</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>33+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android no"><span>Chrome Android</span><span>No</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>4.0–5.0</span></span><span class="opera_android no"><span>Opera Android</span><span>11–14</span></span></div></div></div>

  <p><i>This section is non-normative.</i></p>

  <p>This section introduces shared workers using a Hello World example. Shared workers use slightly
  different APIs, since each worker can have multiple connections.</p>

  <p>This first example shows how you connect to a worker and how a worker can send a message back
  to the page when it connects to it. Received messages are displayed in a log.</p>

  <p>Here is the HTML page:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Shared workers: demo 1<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>pre</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;log&quot;</c-><c- p>&gt;</c->Log:<c- p>&lt;/</c-><c- f>pre</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
  <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> SharedWorker<c- p>(</c-><c- t>&apos;test.js&apos;</c-><c- p>);</c->
  <c- a>var</c-> log <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;log&apos;</c-><c- p>);</c->
  worker<c- p>.</c->port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c-> <c- c1>// note: not worker.onmessage!</c->
    log<c- p>.</c->textContent <c- o>+=</c-> <c- t>&apos;\n&apos;</c-> <c- o>+</c-> e<c- p>.</c->data<c- p>;</c->
  <c- p>}</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
</code></pre>

  <p>Here is the JavaScript worker:</p>

  <pre><code class='js'>onconnect <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> port <c- o>=</c-> e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>];</c->
  port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;Hello World!&apos;</c-><c- p>);</c->
<c- p>}</c->
</code></pre>

  <p><a href=../demos/workers/shared/001/test.html>View this example online</a>.</p>

  <hr>

  <p>This second example extends the first one by changing two things: first, messages are received
  using <code>addEventListener()</code> instead of an <a href=webappapis.html#event-handler-idl-attributes id=shared-workers-introduction:event-handler-idl-attributes>event handler IDL attribute</a>, and second, a message is sent <em>to</em> the
  worker, causing the worker to send another message in return. Received messages are again
  displayed in a log.</p>

  <p>Here is the HTML page:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Shared workers: demo 2<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>pre</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;log&quot;</c-><c- p>&gt;</c->Log:<c- p>&lt;/</c-><c- f>pre</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
  <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> SharedWorker<c- p>(</c-><c- t>&apos;test.js&apos;</c-><c- p>);</c->
  <c- a>var</c-> log <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;log&apos;</c-><c- p>);</c->
  worker<c- p>.</c->port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    log<c- p>.</c->textContent <c- o>+=</c-> <c- t>&apos;\n&apos;</c-> <c- o>+</c-> e<c- p>.</c->data<c- p>;</c->
  <c- p>},</c-> <c- kc>false</c-><c- p>);</c->
  worker<c- p>.</c->port<c- p>.</c->start<c- p>();</c-> <c- c1>// note: need this when using addEventListener</c->
  worker<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;ping&apos;</c-><c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
</code></pre>

  <p>Here is the JavaScript worker:</p>

  <pre><code class='js'>onconnect <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> port <c- o>=</c-> e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>];</c->
  port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;Hello World!&apos;</c-><c- p>);</c->
  port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;pong&apos;</c-><c- p>);</c-> <c- c1>// not e.ports[0].postMessage!</c->
    <c- c1>// e.target.postMessage(&apos;pong&apos;); would work also</c->
  <c- p>}</c->
<c- p>}</c->
</code></pre>

  <p><a href=../demos/workers/shared/002/test.html>View this example online</a>.</p>

  <hr>

  <p>Finally, the example is extended to show how two pages can connect to the same worker; in this
  case, the second page is merely in an <code id=shared-workers-introduction:the-iframe-element><a href=iframe-embed-object.html#the-iframe-element>iframe</a></code> on the first page, but the same
  principle would apply to an entirely separate page in a separate <a id=shared-workers-introduction:top-level-traversable href=document-sequences.html#top-level-traversable>top-level
  traversable</a>.</p>

  <p>Here is the outer HTML page:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Shared workers: demo 3<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>pre</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;log&quot;</c-><c- p>&gt;</c->Log:<c- p>&lt;/</c-><c- f>pre</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
  <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> SharedWorker<c- p>(</c-><c- t>&apos;test.js&apos;</c-><c- p>);</c->
  <c- a>var</c-> log <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;log&apos;</c-><c- p>);</c->
  worker<c- p>.</c->port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    log<c- p>.</c->textContent <c- o>+=</c-> <c- t>&apos;\n&apos;</c-> <c- o>+</c-> e<c- p>.</c->data<c- p>;</c->
  <c- p>},</c-> <c- kc>false</c-><c- p>);</c->
  worker<c- p>.</c->port<c- p>.</c->start<c- p>();</c->
  worker<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;ping&apos;</c-><c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>iframe</c-> <c- e>src</c-><c- o>=</c-><c- s>&quot;inner.html&quot;</c-><c- p>&gt;&lt;/</c-><c- f>iframe</c-><c- p>&gt;</c->
</code></pre>

  <p>Here is the inner HTML page:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Shared workers: demo 3 inner frame<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>pre</c-> <c- e>id</c-><c- o>=</c-><c- s>log</c-><c- p>&gt;</c->Inner log:<c- p>&lt;/</c-><c- f>pre</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
  <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> SharedWorker<c- p>(</c-><c- t>&apos;test.js&apos;</c-><c- p>);</c->
  <c- a>var</c-> log <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;log&apos;</c-><c- p>);</c->
  worker<c- p>.</c->port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
   log<c- p>.</c->textContent <c- o>+=</c-> <c- t>&apos;\n&apos;</c-> <c- o>+</c-> e<c- p>.</c->data<c- p>;</c->
  <c- p>}</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
</code></pre>

  <p>Here is the JavaScript worker:</p>

  <pre><code class='js'><c- a>var</c-> count <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
onconnect <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  count <c- o>+=</c-> <c- mf>1</c-><c- p>;</c->
  <c- a>var</c-> port <c- o>=</c-> e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>];</c->
  port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;Hello World! You are connection #&apos;</c-> <c- o>+</c-> count<c- p>);</c->
  port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-><c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;pong&apos;</c-><c- p>);</c->
  <c- p>}</c->
<c- p>}</c->
</code></pre>

  <p><a href=../demos/workers/shared/003/test.html>View this example online</a>.</p>


  <h5 id=shared-state-using-a-shared-worker><span class=secno>10.1.2.4</span> Shared state using a shared worker<a href=#shared-state-using-a-shared-worker class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>In this example, multiple windows (viewers) can be opened that are all viewing the same map.
  All the windows share the same map information, with a single worker coordinating all the viewers.
  Each viewer can move around independently, but if they set any data on the map, all the viewers
  are updated.</p>

  <p>The main page isn't interesting, it merely provides a way to open the viewers:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>head</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Workers example: Multiviewer<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
   <c- a>function</c-> openViewer<c- p>()</c-> <c- p>{</c->
     window<c- p>.</c->open<c- p>(</c-><c- t>&apos;viewer.html&apos;</c-><c- p>);</c->
   <c- p>}</c->
  <c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>head</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>body</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;openViewer()&quot;</c-><c- p>&gt;</c->Open a new
  viewer<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->Each viewer opens in a new window. You can have as many viewers
  as you like, they all view the same data.<c- p>&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>body</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>html</c-><c- p>&gt;</c->
</code></pre>

  <p>The viewer is more involved:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>head</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Workers example: Multiviewer viewer<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
   <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> SharedWorker<c- p>(</c-><c- t>&apos;worker.js&apos;</c-><c- p>,</c-> <c- t>&apos;core&apos;</c-><c- p>);</c->

   <c- c1>// CONFIGURATION</c->
   <c- a>function</c-> configure<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
     <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>4</c-><c- p>)</c-> <c- o>!=</c-> <c- t>&apos;cfg &apos;</c-><c- p>)</c-> <c- k>return</c-><c- p>;</c->
     <c- a>var</c-> name <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>).</c->split<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>,</c-> <c- mf>1</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
     <c- c1>// update display to mention our name is name</c->
     document<c- p>.</c->getElementsByTagName<c- p>(</c-><c- t>&apos;h1&apos;</c-><c- p>)[</c-><c- mf>0</c-><c- p>].</c->textContent <c- o>+=</c-> <c- t>&apos; &apos;</c-> <c- o>+</c-> name<c- p>;</c->
     <c- c1>// no longer need this listener</c->
     worker<c- p>.</c->port<c- p>.</c->removeEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> configure<c- p>,</c-> <c- kc>false</c-><c- p>);</c->
   <c- p>}</c->
   worker<c- p>.</c->port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> configure<c- p>,</c-> <c- kc>false</c-><c- p>);</c->

   <c- c1>// MAP</c->
   <c- a>function</c-> paintMap<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
     <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>4</c-><c- p>)</c-> <c- o>!=</c-> <c- t>&apos;map &apos;</c-><c- p>)</c-> <c- k>return</c-><c- p>;</c->
     <c- a>var</c-> data <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>).</c->split<c- p>(</c-><c- t>&apos;,&apos;</c-><c- p>);</c->
     <c- c1>// display tiles data[0] .. data[8]</c->
     <c- a>var</c-> canvas <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;map&apos;</c-><c- p>);</c->
     <c- a>var</c-> context <c- o>=</c-> canvas<c- p>.</c->getContext<c- p>(</c-><c- t>&apos;2d&apos;</c-><c- p>);</c->
     <c- k>for</c-> <c- p>(</c-><c- a>var</c-> y <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> y <c- o>&lt;</c-> <c- mf>3</c-><c- p>;</c-> y <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
       <c- k>for</c-> <c- p>(</c-><c- a>var</c-> x <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> x <c- o>&lt;</c-> <c- mf>3</c-><c- p>;</c-> x <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
         <c- a>var</c-> tile <c- o>=</c-> data<c- p>[</c->y <c- o>*</c-> <c- mf>3</c-> <c- o>+</c-> x<c- p>];</c->
         <c- k>if</c-> <c- p>(</c->tile <c- o>==</c-> <c- t>&apos;0&apos;</c-><c- p>)</c->
           context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;green&apos;</c-><c- p>;</c->
         <c- k>else</c->
           context<c- p>.</c->fillStyle <c- o>=</c-> <c- t>&apos;maroon&apos;</c-><c- p>;</c->
         context<c- p>.</c->fillRect<c- p>(</c->x <c- o>*</c-> <c- mf>50</c-><c- p>,</c-> y <c- o>*</c-> <c- mf>50</c-><c- p>,</c-> <c- mf>50</c-><c- p>,</c-> <c- mf>50</c-><c- p>);</c->
       <c- p>}</c->
     <c- p>}</c->
   <c- p>}</c->
   worker<c- p>.</c->port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> paintMap<c- p>,</c-> <c- kc>false</c-><c- p>);</c->

   <c- c1>// PUBLIC CHAT</c->
   <c- a>function</c-> updatePublicChat<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
     <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>4</c-><c- p>)</c-> <c- o>!=</c-> <c- t>&apos;txt &apos;</c-><c- p>)</c-> <c- k>return</c-><c- p>;</c->
     <c- a>var</c-> name <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>).</c->split<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>,</c-> <c- mf>1</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
     <c- a>var</c-> message <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-> <c- o>+</c-> name<c- p>.</c->length <c- o>+</c-> <c- mf>1</c-><c- p>);</c->
     <c- c1>// display &quot;&lt;name&gt; message&quot; in public chat</c->
     <c- a>var</c-> public <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;public&apos;</c-><c- p>);</c->
     <c- a>var</c-> p <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;p&apos;</c-><c- p>);</c->
     <c- a>var</c-> n <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;button&apos;</c-><c- p>);</c->
     n<c- p>.</c->textContent <c- o>=</c-> <c- t>&apos;&lt;&apos;</c-> <c- o>+</c-> name <c- o>+</c-> <c- t>&apos;&gt; &apos;</c-><c- p>;</c->
     n<c- p>.</c->onclick <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c-> worker<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;msg &apos;</c-> <c- o>+</c-> name<c- p>);</c-> <c- p>};</c->
     p<c- p>.</c->appendChild<c- p>(</c->n<c- p>);</c->
     <c- a>var</c-> m <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;span&apos;</c-><c- p>);</c->
     m<c- p>.</c->textContent <c- o>=</c-> message<c- p>;</c->
     p<c- p>.</c->appendChild<c- p>(</c->m<c- p>);</c->
     public<c- p>.</c->appendChild<c- p>(</c->p<c- p>);</c->
   <c- p>}</c->
   worker<c- p>.</c->port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> updatePublicChat<c- p>,</c-> <c- kc>false</c-><c- p>);</c->

   <c- c1>// PRIVATE CHAT</c->
   <c- a>function</c-> startPrivateChat<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
     <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>4</c-><c- p>)</c-> <c- o>!=</c-> <c- t>&apos;msg &apos;</c-><c- p>)</c-> <c- k>return</c-><c- p>;</c->
     <c- a>var</c-> name <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>).</c->split<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>,</c-> <c- mf>1</c-><c- p>)[</c-><c- mf>0</c-><c- p>];</c->
     <c- a>var</c-> port <c- o>=</c-> event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>];</c->
     <c- c1>// display a private chat UI</c->
     <c- a>var</c-> ul <c- o>=</c-> document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;private&apos;</c-><c- p>);</c->
     <c- a>var</c-> li <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;li&apos;</c-><c- p>);</c->
     <c- a>var</c-> h3 <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;h3&apos;</c-><c- p>);</c->
     h3<c- p>.</c->textContent <c- o>=</c-> <c- t>&apos;Private chat with &apos;</c-> <c- o>+</c-> name<c- p>;</c->
     li<c- p>.</c->appendChild<c- p>(</c->h3<c- p>);</c->
     <c- a>var</c-> div <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;div&apos;</c-><c- p>);</c->
     <c- a>var</c-> addMessage <c- o>=</c-> <c- a>function</c-><c- p>(</c->name<c- p>,</c-> message<c- p>)</c-> <c- p>{</c->
       <c- a>var</c-> p <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;p&apos;</c-><c- p>);</c->
       <c- a>var</c-> n <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;strong&apos;</c-><c- p>);</c->
       n<c- p>.</c->textContent <c- o>=</c-> <c- t>&apos;&lt;&apos;</c-> <c- o>+</c-> name <c- o>+</c-> <c- t>&apos;&gt; &apos;</c-><c- p>;</c->
       p<c- p>.</c->appendChild<c- p>(</c->n<c- p>);</c->
       <c- a>var</c-> t <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;span&apos;</c-><c- p>);</c->
       t<c- p>.</c->textContent <c- o>=</c-> message<c- p>;</c->
       p<c- p>.</c->appendChild<c- p>(</c->t<c- p>);</c->
       div<c- p>.</c->appendChild<c- p>(</c->p<c- p>);</c->
     <c- p>};</c->
     port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
       addMessage<c- p>(</c->name<c- p>,</c-> event<c- p>.</c->data<c- p>);</c->
     <c- p>};</c->
     li<c- p>.</c->appendChild<c- p>(</c->div<c- p>);</c->
     <c- a>var</c-> form <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;form&apos;</c-><c- p>);</c->
     <c- a>var</c-> p <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;p&apos;</c-><c- p>);</c->
     <c- a>var</c-> input <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;input&apos;</c-><c- p>);</c->
     input<c- p>.</c->size <c- o>=</c-> <c- mf>50</c-><c- p>;</c->
     p<c- p>.</c->appendChild<c- p>(</c->input<c- p>);</c->
     p<c- p>.</c->appendChild<c- p>(</c->document<c- p>.</c->createTextNode<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>));</c->
     <c- a>var</c-> button <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- t>&apos;button&apos;</c-><c- p>);</c->
     button<c- p>.</c->textContent <c- o>=</c-> <c- t>&apos;Post&apos;</c-><c- p>;</c->
     p<c- p>.</c->appendChild<c- p>(</c->button<c- p>);</c->
     form<c- p>.</c->onsubmit <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c->
       port<c- p>.</c->postMessage<c- p>(</c->input<c- p>.</c->value<c- p>);</c->
       addMessage<c- p>(</c-><c- t>&apos;me&apos;</c-><c- p>,</c-> input<c- p>.</c->value<c- p>);</c->
       input<c- p>.</c->value <c- o>=</c-> <c- t>&apos;&apos;</c-><c- p>;</c->
       <c- k>return</c-> <c- kc>false</c-><c- p>;</c->
     <c- p>};</c->
     form<c- p>.</c->appendChild<c- p>(</c->p<c- p>);</c->
     li<c- p>.</c->appendChild<c- p>(</c->form<c- p>);</c->
     ul<c- p>.</c->appendChild<c- p>(</c->li<c- p>);</c->
   <c- p>}</c->
   worker<c- p>.</c->port<c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;message&apos;</c-><c- p>,</c-> startPrivateChat<c- p>,</c-> <c- kc>false</c-><c- p>);</c->

   worker<c- p>.</c->port<c- p>.</c->start<c- p>();</c->
  <c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>head</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>body</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>h1</c-><c- p>&gt;</c->Viewer<c- p>&lt;/</c-><c- f>h1</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>h2</c-><c- p>&gt;</c->Map<c- p>&lt;/</c-><c- f>h2</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;&lt;</c-><c- f>canvas</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;map&quot;</c-> <c- e>height</c-><c- o>=</c-><c- s>150</c-> <c- e>width</c-><c- o>=</c-><c- s>150</c-><c- p>&gt;&lt;/</c-><c- f>canvas</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;mov left&apos;)&quot;</c-><c- p>&gt;</c->Left<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;mov up&apos;)&quot;</c-><c- p>&gt;</c->Up<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;mov down&apos;)&quot;</c-><c- p>&gt;</c->Down<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;mov right&apos;)&quot;</c-><c- p>&gt;</c->Right<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;set 0&apos;)&quot;</c-><c- p>&gt;</c->Set 0<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>button</c-> <c- e>type</c-><c- o>=</c-><c- s>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;set 1&apos;)&quot;</c-><c- p>&gt;</c->Set 1<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
  <c- p>&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>h2</c-><c- p>&gt;</c->Public Chat<c- p>&lt;/</c-><c- f>h2</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>div</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;public&quot;</c-><c- p>&gt;&lt;/</c-><c- f>div</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>form</c-> <c- e>onsubmit</c-><c- o>=</c-><c- s>&quot;worker.port.postMessage(&apos;txt &apos; + message.value); message.value = &apos;&apos;; return false;&quot;</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->
    <c- p>&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>&quot;text&quot;</c-> <c- e>name</c-><c- o>=</c-><c- s>&quot;message&quot;</c-> <c- e>size</c-><c- o>=</c-><c- s>&quot;50&quot;</c-><c- p>&gt;</c->
    <c- p>&lt;</c-><c- f>button</c-><c- p>&gt;</c->Post<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c->
   <c- p>&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;/</c-><c- f>form</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>h2</c-><c- p>&gt;</c->Private Chat<c- p>&lt;/</c-><c- f>h2</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>ul</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;private&quot;</c-><c- p>&gt;&lt;/</c-><c- f>ul</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>body</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>html</c-><c- p>&gt;</c->
</code></pre>

  <p>There are several key things worth noting about the way the viewer is written.</p>

  <p><strong>Multiple listeners</strong>. Instead of a single message processing function, the code
  here attaches multiple event listeners, each one performing a quick check to see if it is relevant
  for the message. In this example it doesn't make much difference, but if multiple authors wanted
  to collaborate using a single port to communicate with a worker, it would allow for independent
  code instead of changes having to all be made to a single event handling function.</p>

  <p>Registering event listeners in this way also allows you to unregister specific listeners when
  you are done with them, as is done with the <code>configure()</code> method in this
  example.</p>

  <p>Finally, the worker:</p>

  <pre><code class='js'><c- a>var</c-> nextName <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
<c- a>function</c-> getNextName<c- p>()</c-> <c- p>{</c->
  <c- c1>// this could use more friendly names</c->
  <c- c1>// but for now just return a number</c->
  <c- k>return</c-> nextName<c- o>++</c-><c- p>;</c->
<c- p>}</c->

<c- a>var</c-> map <c- o>=</c-> <c- p>[</c->
 <c- p>[</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>],</c->
 <c- p>[</c-><c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>],</c->
 <c- p>[</c-><c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>],</c->
 <c- p>[</c-><c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>],</c->
 <c- p>[</c-><c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>],</c->
 <c- p>[</c-><c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>],</c->
 <c- p>[</c-><c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>1</c-><c- p>,</c-> <c- mf>0</c-><c- p>,</c-> <c- mf>1</c-><c- p>],</c->
<c- p>];</c->

<c- a>function</c-> wrapX<c- p>(</c->x<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->x <c- o>&lt;</c-> <c- mf>0</c-><c- p>)</c-> <c- k>return</c-> wrapX<c- p>(</c->x <c- o>+</c-> map<c- p>[</c-><c- mf>0</c-><c- p>].</c->length<c- p>);</c->
  <c- k>if</c-> <c- p>(</c->x <c- o>&gt;=</c-> map<c- p>[</c-><c- mf>0</c-><c- p>].</c->length<c- p>)</c-> <c- k>return</c-> wrapX<c- p>(</c->x <c- o>-</c-> map<c- p>[</c-><c- mf>0</c-><c- p>].</c->length<c- p>);</c->
  <c- k>return</c-> x<c- p>;</c->
<c- p>}</c->

<c- a>function</c-> wrapY<c- p>(</c->y<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->y <c- o>&lt;</c-> <c- mf>0</c-><c- p>)</c-> <c- k>return</c-> wrapY<c- p>(</c->y <c- o>+</c-> map<c- p>.</c->length<c- p>);</c->
  <c- k>if</c-> <c- p>(</c->y <c- o>&gt;=</c-> map<c- p>[</c-><c- mf>0</c-><c- p>].</c->length<c- p>)</c-> <c- k>return</c-> wrapY<c- p>(</c->y <c- o>-</c-> map<c- p>.</c->length<c- p>);</c->
  <c- k>return</c-> y<c- p>;</c->
<c- p>}</c->

<c- a>function</c-> wrap<c- p>(</c->val<c- p>,</c-> min<c- p>,</c-> max<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->val <c- o>&lt;</c-> min<c- p>)</c->
    <c- k>return</c-> val <c- o>+</c-> <c- p>(</c->max<c- o>-</c->min<c- p>)</c-><c- o>+</c-><c- mf>1</c-><c- p>;</c->
  <c- k>if</c-> <c- p>(</c->val <c- o>&gt;</c-> max<c- p>)</c->
    <c- k>return</c-> val <c- o>-</c-> <c- p>(</c->max<c- o>-</c->min<c- p>)</c-><c- o>-</c-><c- mf>1</c-><c- p>;</c->
  <c- k>return</c-> val<c- p>;</c->
<c- p>}</c->

<c- a>function</c-> sendMapData<c- p>(</c->viewer<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> data <c- o>=</c-> <c- t>&apos;&apos;</c-><c- p>;</c->
  <c- k>for</c-> <c- p>(</c-><c- a>var</c-> y <c- o>=</c-> viewer<c- p>.</c->y<c- o>-</c-><c- mf>1</c-><c- p>;</c-> y <c- o>&lt;=</c-> viewer<c- p>.</c->y<c- o>+</c-><c- mf>1</c-><c- p>;</c-> y <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
    <c- k>for</c-> <c- p>(</c-><c- a>var</c-> x <c- o>=</c-> viewer<c- p>.</c->x<c- o>-</c-><c- mf>1</c-><c- p>;</c-> x <c- o>&lt;=</c-> viewer<c- p>.</c->x<c- o>+</c-><c- mf>1</c-><c- p>;</c-> x <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
      <c- k>if</c-> <c- p>(</c->data <c- o>!=</c-> <c- t>&apos;&apos;</c-><c- p>)</c->
        data <c- o>+=</c-> <c- t>&apos;,&apos;</c-><c- p>;</c->
      data <c- o>+=</c-> map<c- p>[</c->wrap<c- p>(</c->y<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> map<c- p>[</c-><c- mf>0</c-><c- p>].</c->length<c- o>-</c-><c- mf>1</c-><c- p>)][</c->wrap<c- p>(</c->x<c- p>,</c-> <c- mf>0</c-><c- p>,</c-> map<c- p>.</c->length<c- o>-</c-><c- mf>1</c-><c- p>)];</c->
    <c- p>}</c->
  <c- p>}</c->
  viewer<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;map &apos;</c-> <c- o>+</c-> data<c- p>);</c->
<c- p>}</c->

<c- a>var</c-> viewers <c- o>=</c-> <c- p>{};</c->
onconnect <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> name <c- o>=</c-> getNextName<c- p>();</c->
  event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->_data <c- o>=</c-> <c- p>{</c-> port<c- o>:</c-> event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>],</c-> name<c- o>:</c-> name<c- p>,</c-> x<c- o>:</c-> <c- mf>0</c-><c- p>,</c-> y<c- o>:</c-> <c- mf>0</c-><c- p>,</c-> <c- p>};</c->
  viewers<c- p>[</c->name<c- p>]</c-> <c- o>=</c-> event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->_data<c- p>;</c->
  event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->postMessage<c- p>(</c-><c- t>&apos;cfg &apos;</c-> <c- o>+</c-> name<c- p>);</c->
  event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->onmessage <c- o>=</c-> getMessage<c- p>;</c->
  sendMapData<c- p>(</c->event<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->_data<c- p>);</c->
<c- p>};</c->

<c- a>function</c-> getMessage<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  <c- k>switch</c-> <c- p>(</c->event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>0</c-><c- p>,</c-> <c- mf>4</c-><c- p>))</c-> <c- p>{</c->
    <c- k>case</c-> <c- t>&apos;mov &apos;</c-><c- o>:</c->
      <c- a>var</c-> direction <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>);</c->
      <c- a>var</c-> dx <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
      <c- a>var</c-> dy <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
      <c- k>switch</c-> <c- p>(</c->direction<c- p>)</c-> <c- p>{</c->
        <c- k>case</c-> <c- t>&apos;up&apos;</c-><c- o>:</c-> dy <c- o>=</c-> <c- o>-</c-><c- mf>1</c-><c- p>;</c-> <c- k>break</c-><c- p>;</c->
        <c- k>case</c-> <c- t>&apos;down&apos;</c-><c- o>:</c-> dy <c- o>=</c-> <c- mf>1</c-><c- p>;</c-> <c- k>break</c-><c- p>;</c->
        <c- k>case</c-> <c- t>&apos;left&apos;</c-><c- o>:</c-> dx <c- o>=</c-> <c- o>-</c-><c- mf>1</c-><c- p>;</c-> <c- k>break</c-><c- p>;</c->
        <c- k>case</c-> <c- t>&apos;right&apos;</c-><c- o>:</c-> dx <c- o>=</c-> <c- mf>1</c-><c- p>;</c-> <c- k>break</c-><c- p>;</c->
      <c- p>}</c->
      event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->x <c- o>=</c-> wrapX<c- p>(</c->event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->x <c- o>+</c-> dx<c- p>);</c->
      event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->y <c- o>=</c-> wrapY<c- p>(</c->event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->y <c- o>+</c-> dy<c- p>);</c->
      sendMapData<c- p>(</c->event<c- p>.</c->target<c- p>.</c->_data<c- p>);</c->
      <c- k>break</c-><c- p>;</c->
    <c- k>case</c-> <c- t>&apos;set &apos;</c-><c- o>:</c->
      <c- a>var</c-> value <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>);</c->
      map<c- p>[</c->event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->y<c- p>][</c->event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->x<c- p>]</c-> <c- o>=</c-> value<c- p>;</c->
      <c- k>for</c-> <c- p>(</c-><c- a>var</c-> viewer <c- k>in</c-> viewers<c- p>)</c->
        sendMapData<c- p>(</c->viewers<c- p>[</c->viewer<c- p>]);</c->
      <c- k>break</c-><c- p>;</c->
    <c- k>case</c-> <c- t>&apos;txt &apos;</c-><c- o>:</c->
      <c- a>var</c-> name <c- o>=</c-> event<c- p>.</c->target<c- p>.</c->_data<c- p>.</c->name<c- p>;</c->
      <c- a>var</c-> message <c- o>=</c-> event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>);</c->
      <c- k>for</c-> <c- p>(</c-><c- a>var</c-> viewer <c- k>in</c-> viewers<c- p>)</c->
        viewers<c- p>[</c->viewer<c- p>].</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;txt &apos;</c-> <c- o>+</c-> name <c- o>+</c-> <c- t>&apos; &apos;</c-> <c- o>+</c-> message<c- p>);</c->
      <c- k>break</c-><c- p>;</c->
    <c- k>case</c-> <c- t>&apos;msg &apos;</c-><c- o>:</c->
      <c- a>var</c-> party1 <c- o>=</c-> event<c- p>.</c->target<c- p>.</c->_data<c- p>;</c->
      <c- a>var</c-> party2 <c- o>=</c-> viewers<c- p>[</c->event<c- p>.</c->data<c- p>.</c->substr<c- p>(</c-><c- mf>4</c-><c- p>).</c->split<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>,</c-> <c- mf>1</c-><c- p>)[</c-><c- mf>0</c-><c- p>]];</c->
      <c- k>if</c-> <c- p>(</c->party2<c- p>)</c-> <c- p>{</c->
        <c- a>var</c-> channel <c- o>=</c-> <c- k>new</c-> MessageChannel<c- p>();</c->
        party1<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;msg &apos;</c-> <c- o>+</c-> party2<c- p>.</c->name<c- p>,</c-> <c- p>[</c->channel<c- p>.</c->port1<c- p>]);</c->
        party2<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;msg &apos;</c-> <c- o>+</c-> party1<c- p>.</c->name<c- p>,</c-> <c- p>[</c->channel<c- p>.</c->port2<c- p>]);</c->
      <c- p>}</c->
      <c- k>break</c-><c- p>;</c->
  <c- p>}</c->
<c- p>}</c->
</code></pre>

  <p><strong>Connecting to multiple pages</strong>. The script uses the <code id=shared-state-using-a-shared-worker:handler-sharedworkerglobalscope-onconnect><a href=#handler-sharedworkerglobalscope-onconnect>onconnect</a></code> event listener to listen for
  multiple connections.</p>

  <p><strong>Direct channels</strong>. When the worker receives a "msg" message from one viewer
  naming another viewer, it sets up a direct connection between the two, so that the two viewers can
  communicate directly without the worker having to proxy all the messages.</p>

  <p><a href=../demos/workers/multiviewer/page.html>View this example online</a>.</p>


  <h5 id=delegation><span class=secno>10.1.2.5</span> Delegation<a href=#delegation class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>With multicore CPUs becoming prevalent, one way to obtain better performance is to split
  computationally expensive tasks amongst multiple workers. In this example, a computationally
  expensive task that is to be performed for every number from 1 to 10,000,000 is farmed out to ten
  subworkers.</p>

  <p>The main page is as follows, it just reports the result:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>head</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Worker example: Multicore computation<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>head</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>body</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;</c->Result: <c- p>&lt;</c-><c- f>output</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;result&quot;</c-><c- p>&gt;&lt;/</c-><c- f>output</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
   <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;worker.js&apos;</c-><c- p>);</c->
   worker<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
     document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;result&apos;</c-><c- p>).</c->textContent <c- o>=</c-> event<c- p>.</c->data<c- p>;</c->
   <c- p>};</c->
  <c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>body</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>html</c-><c- p>&gt;</c->
</code></pre>

  <p>The worker itself is as follows:</p>

  <pre><code class='js'><c- c1>// settings</c->
<c- a>var</c-> num_workers <c- o>=</c-> <c- mf>10</c-><c- p>;</c->
<c- a>var</c-> items_per_worker <c- o>=</c-> <c- mf>1000000</c-><c- p>;</c->

<c- c1>// start the workers</c->
<c- a>var</c-> result <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
<c- a>var</c-> pending_workers <c- o>=</c-> num_workers<c- p>;</c->
<c- k>for</c-> <c- p>(</c-><c- a>var</c-> i <c- o>=</c-> <c- mf>0</c-><c- p>;</c-> i <c- o>&lt;</c-> num_workers<c- p>;</c-> i <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;core.js&apos;</c-><c- p>);</c->
  worker<c- p>.</c->postMessage<c- p>(</c->i <c- o>*</c-> items_per_worker<c- p>);</c->
  worker<c- p>.</c->postMessage<c- p>((</c->i<c- o>+</c-><c- mf>1</c-><c- p>)</c-> <c- o>*</c-> items_per_worker<c- p>);</c->
  worker<c- p>.</c->onmessage <c- o>=</c-> storeResult<c- p>;</c->
<c- p>}</c->

<c- c1>// handle the results</c->
<c- a>function</c-> storeResult<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  result <c- o>+=</c-> <c- mf>1</c-><c- o>*</c->event<c- p>.</c->data<c- p>;</c->
  pending_workers <c- o>-=</c-> <c- mf>1</c-><c- p>;</c->
  <c- k>if</c-> <c- p>(</c->pending_workers <c- o>&lt;=</c-> <c- mf>0</c-><c- p>)</c->
    postMessage<c- p>(</c->result<c- p>);</c-> <c- c1>// finished!</c->
<c- p>}</c->
</code></pre>

  <p>It consists of a loop to start the subworkers, and then a handler
  that waits for all the subworkers to respond.</p>

  <p>The subworkers are implemented as follows:</p>

  <pre><code class='js'><c- a>var</c-> start<c- p>;</c->
onmessage <c- o>=</c-> getStart<c- p>;</c->
<c- a>function</c-> getStart<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  start <c- o>=</c-> <c- mf>1</c-><c- o>*</c->event<c- p>.</c->data<c- p>;</c->
  onmessage <c- o>=</c-> getEnd<c- p>;</c->
<c- p>}</c->

<c- a>var</c-> end<c- p>;</c->
<c- a>function</c-> getEnd<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  end <c- o>=</c-> <c- mf>1</c-><c- o>*</c->event<c- p>.</c->data<c- p>;</c->
  onmessage <c- o>=</c-> <c- kc>null</c-><c- p>;</c->
  work<c- p>();</c->
<c- p>}</c->

<c- a>function</c-> work<c- p>()</c-> <c- p>{</c->
  <c- a>var</c-> result <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
  <c- k>for</c-> <c- p>(</c-><c- a>var</c-> i <c- o>=</c-> start<c- p>;</c-> i <c- o>&lt;</c-> end<c- p>;</c-> i <c- o>+=</c-> <c- mf>1</c-><c- p>)</c-> <c- p>{</c->
    <c- c1>// perform some complex calculation here</c->
    result <c- o>+=</c-> <c- mf>1</c-><c- p>;</c->
  <c- p>}</c->
  postMessage<c- p>(</c->result<c- p>);</c->
  close<c- p>();</c->
<c- p>}</c->
</code></pre>

  <p>They receive two numbers in two events, perform the computation for the range of numbers thus
  specified, and then report the result back to the parent.</p>

  <p><a href=../demos/workers/multicore/page.html>View this example online</a>.</p>


  <h5 id=providing-libraries><span class=secno>10.1.2.6</span> Providing libraries<a href=#providing-libraries class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Suppose that a cryptography library is made available that provides three tasks:</p>

  <dl><dt>Generate a public/private key pair<dd>Takes a port, on which it will send two messages, first the public key and then the private
   key.<dt>Given a plaintext and a public key, return the corresponding ciphertext<dd>Takes a port, to which any number of messages can be sent, the first giving the public key,
   and the remainder giving the plaintext, each of which is encrypted and then sent on that same
   channel as the ciphertext. The user can close the port when it is done encrypting content.<dt>Given a ciphertext and a private key, return the corresponding plaintext<dd>Takes a port, to which any number of messages can be sent, the first giving the private key,
   and the remainder giving the ciphertext, each of which is decrypted and then sent on that same
   channel as the plaintext. The user can close the port when it is done decrypting content.</dl>

  <p>The library itself is as follows:</p>

  <pre><code class='js'><c- a>function</c-> handleMessage<c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- u>&quot;genkeys&quot;</c-><c- p>)</c->
    genkeys<c- p>(</c->e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
  <c- k>else</c-> <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- u>&quot;encrypt&quot;</c-><c- p>)</c->
    encrypt<c- p>(</c->e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
  <c- k>else</c-> <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- u>&quot;decrypt&quot;</c-><c- p>)</c->
    decrypt<c- p>(</c->e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
<c- p>}</c->

<c- a>function</c-> genkeys<c- p>(</c->p<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> keys <c- o>=</c-> _generateKeyPair<c- p>();</c->
  p<c- p>.</c->postMessage<c- p>(</c->keys<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
  p<c- p>.</c->postMessage<c- p>(</c->keys<c- p>[</c-><c- mf>1</c-><c- p>]);</c->
<c- p>}</c->

<c- a>function</c-> encrypt<c- p>(</c->p<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> key<c- p>,</c-> state <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
  p<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->state <c- o>==</c-> <c- mf>0</c-><c- p>)</c-> <c- p>{</c->
      key <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
      state <c- o>=</c-> <c- mf>1</c-><c- p>;</c->
    <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
      p<c- p>.</c->postMessage<c- p>(</c->_encrypt<c- p>(</c->key<c- p>,</c-> e<c- p>.</c->data<c- p>));</c->
    <c- p>}</c->
  <c- p>};</c->
<c- p>}</c->

<c- a>function</c-> decrypt<c- p>(</c->p<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> key<c- p>,</c-> state <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
  p<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->state <c- o>==</c-> <c- mf>0</c-><c- p>)</c-> <c- p>{</c->
      key <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
      state <c- o>=</c-> <c- mf>1</c-><c- p>;</c->
    <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
      p<c- p>.</c->postMessage<c- p>(</c->_decrypt<c- p>(</c->key<c- p>,</c-> e<c- p>.</c->data<c- p>));</c->
    <c- p>}</c->
  <c- p>};</c->
<c- p>}</c->

<c- c1>// support being used as a shared worker as well as a dedicated worker</c->
<c- k>if</c-> <c- p>(</c-><c- t>&apos;onmessage&apos;</c-> <c- k>in</c-> <c- k>this</c-><c- p>)</c-> <c- c1>// dedicated worker</c->
  onmessage <c- o>=</c-> handleMessage<c- p>;</c->
<c- k>else</c-> <c- c1>// shared worker</c->
  onconnect <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c-> e<c- p>.</c->port<c- p>.</c->onmessage <c- o>=</c-> handleMessage<c- p>;</c-> <c- p>}</c->


<c- c1>// the &quot;crypto&quot; functions:</c->

<c- a>function</c-> _generateKeyPair<c- p>()</c-> <c- p>{</c->
  <c- k>return</c-> <c- p>[</c->Math<c- p>.</c->random<c- p>(),</c-> Math<c- p>.</c->random<c- p>()];</c->
<c- p>}</c->

<c- a>function</c-> _encrypt<c- p>(</c->k<c- p>,</c-> s<c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- t>&apos;encrypted-&apos;</c-> <c- o>+</c-> k <c- o>+</c-> <c- t>&apos; &apos;</c-> <c- o>+</c-> s<c- p>;</c->
<c- p>}</c->

<c- a>function</c-> _decrypt<c- p>(</c->k<c- p>,</c-> s<c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> s<c- p>.</c->substr<c- p>(</c->s<c- p>.</c->indexOf<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>)</c-><c- o>+</c-><c- mf>1</c-><c- p>);</c->
<c- p>}</c->
</code></pre>

  <p>Note that the crypto functions here are just stubs and don't do real cryptography.</p>

  <p>This library could be used as follows:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE HTML&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>head</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>meta</c-> <c- e>charset</c-><c- o>=</c-><c- s>&quot;utf-8&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Worker example: Crypto library<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
   <c- a>const</c-> cryptoLib <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;libcrypto-v1.js&apos;</c-><c- p>);</c-> <c- c1>// or could use &apos;libcrypto-v2.js&apos;</c->
   <c- a>function</c-> startConversation<c- p>(</c->source<c- p>,</c-> message<c- p>)</c-> <c- p>{</c->
     <c- a>const</c-> messageChannel <c- o>=</c-> <c- k>new</c-> MessageChannel<c- p>();</c->
     source<c- p>.</c->postMessage<c- p>(</c->message<c- p>,</c-> <c- p>[</c->messageChannel<c- p>.</c->port2<c- p>]);</c->
     <c- k>return</c-> messageChannel<c- p>.</c->port1<c- p>;</c->
   <c- p>}</c->
   <c- a>function</c-> getKeys<c- p>()</c-> <c- p>{</c->
     <c- a>let</c-> state <c- o>=</c-> <c- mf>0</c-><c- p>;</c->
     startConversation<c- p>(</c->cryptoLib<c- p>,</c-> <c- u>&quot;genkeys&quot;</c-><c- p>).</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
       <c- k>if</c-> <c- p>(</c->state <c- o>===</c-> <c- mf>0</c-><c- p>)</c->
         document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;public&apos;</c-><c- p>).</c->value <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
       <c- k>else</c-> <c- k>if</c-> <c- p>(</c->state <c- o>===</c-> <c- mf>1</c-><c- p>)</c->
         document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;private&apos;</c-><c- p>).</c->value <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
       state <c- o>+=</c-> <c- mf>1</c-><c- p>;</c->
     <c- p>};</c->
   <c- p>}</c->
   <c- a>function</c-> enc<c- p>()</c-> <c- p>{</c->
     <c- a>const</c-> port <c- o>=</c-> startConversation<c- p>(</c->cryptoLib<c- p>,</c-> <c- u>&quot;encrypt&quot;</c-><c- p>);</c->
     port<c- p>.</c->postMessage<c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;public&apos;</c-><c- p>).</c->value<c- p>);</c->
     port<c- p>.</c->postMessage<c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;input&apos;</c-><c- p>).</c->value<c- p>);</c->
     port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
       document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;input&apos;</c-><c- p>).</c->value <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
       port<c- p>.</c->close<c- p>();</c->
     <c- p>};</c->
   <c- p>}</c->
   <c- a>function</c-> dec<c- p>()</c-> <c- p>{</c->
     <c- a>const</c-> port <c- o>=</c-> startConversation<c- p>(</c->cryptoLib<c- p>,</c-> <c- u>&quot;decrypt&quot;</c-><c- p>);</c->
     port<c- p>.</c->postMessage<c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;private&apos;</c-><c- p>).</c->value<c- p>);</c->
     port<c- p>.</c->postMessage<c- p>(</c->document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;input&apos;</c-><c- p>).</c->value<c- p>);</c->
     port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
       document<c- p>.</c->getElementById<c- p>(</c-><c- t>&apos;input&apos;</c-><c- p>).</c->value <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
       port<c- p>.</c->close<c- p>();</c->
     <c- p>};</c->
   <c- p>}</c->
  <c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>style</c-><c- p>&gt;</c->
   <c- f>textarea</c-> <c- p>{</c-> <c- k>display</c-><c- p>:</c-> <c- kc>block</c-><c- p>;</c-> <c- p>}</c->
  <c- p>&lt;/</c-><c- f>style</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>head</c-><c- p>&gt;</c->
 <c- p>&lt;</c-><c- f>body</c-> <c- e>onload</c-><c- o>=</c-><c- s>&quot;getKeys()&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>fieldset</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>legend</c-><c- p>&gt;</c->Keys<c- p>&lt;/</c-><c- f>legend</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;&lt;</c-><c- f>label</c-><c- p>&gt;</c->Public Key: <c- p>&lt;</c-><c- f>textarea</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;public&quot;</c-><c- p>&gt;&lt;/</c-><c- f>textarea</c-><c- p>&gt;&lt;/</c-><c- f>label</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
   <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;&lt;</c-><c- f>label</c-><c- p>&gt;</c->Private Key: <c- p>&lt;</c-><c- f>textarea</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;private&quot;</c-><c- p>&gt;&lt;/</c-><c- f>textarea</c-><c- p>&gt;&lt;/</c-><c- f>label</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;/</c-><c- f>fieldset</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;&lt;</c-><c- f>label</c-><c- p>&gt;</c->Input: <c- p>&lt;</c-><c- f>textarea</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;input&quot;</c-><c- p>&gt;&lt;/</c-><c- f>textarea</c-><c- p>&gt;&lt;/</c-><c- f>label</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>p</c-><c- p>&gt;&lt;</c-><c- f>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;enc()&quot;</c-><c- p>&gt;</c->Encrypt<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c-> <c- p>&lt;</c-><c- f>button</c-> <c- e>onclick</c-><c- o>=</c-><c- s>&quot;dec()&quot;</c-><c- p>&gt;</c->Decrypt<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;&lt;/</c-><c- f>p</c-><c- p>&gt;</c->
 <c- p>&lt;/</c-><c- f>body</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>html</c-><c- p>&gt;</c->
</code></pre>

  <p>A later version of the API, though, might want to offload all the crypto work onto subworkers.
  This could be done as follows:</p>

  <pre><code class='js'><c- a>function</c-> handleMessage<c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- u>&quot;genkeys&quot;</c-><c- p>)</c->
    genkeys<c- p>(</c->e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
  <c- k>else</c-> <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- u>&quot;encrypt&quot;</c-><c- p>)</c->
    encrypt<c- p>(</c->e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
  <c- k>else</c-> <c- k>if</c-> <c- p>(</c->e<c- p>.</c->data <c- o>==</c-> <c- u>&quot;decrypt&quot;</c-><c- p>)</c->
    decrypt<c- p>(</c->e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
<c- p>}</c->

<c- a>function</c-> genkeys<c- p>(</c->p<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> generator <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;libcrypto-v2-generator.js&apos;</c-><c- p>);</c->
  generator<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;&apos;</c-><c- p>,</c-> <c- p>[</c->p<c- p>]);</c->
<c- p>}</c->

<c- a>function</c-> encrypt<c- p>(</c->p<c- p>)</c-> <c- p>{</c->
  p<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    <c- a>var</c-> key <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
    <c- a>var</c-> encryptor <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;libcrypto-v2-encryptor.js&apos;</c-><c- p>);</c->
    encryptor<c- p>.</c->postMessage<c- p>(</c->key<c- p>,</c-> <c- p>[</c->p<c- p>]);</c->
  <c- p>};</c->
<c- p>}</c->

<c- a>function</c-> encrypt<c- p>(</c->p<c- p>)</c-> <c- p>{</c->
  p<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    <c- a>var</c-> key <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
    <c- a>var</c-> decryptor <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;libcrypto-v2-decryptor.js&apos;</c-><c- p>);</c->
    decryptor<c- p>.</c->postMessage<c- p>(</c->key<c- p>,</c-> <c- p>[</c->p<c- p>]);</c->
  <c- p>};</c->
<c- p>}</c->

<c- c1>// support being used as a shared worker as well as a dedicated worker</c->
<c- k>if</c-> <c- p>(</c-><c- t>&apos;onmessage&apos;</c-> <c- k>in</c-> <c- k>this</c-><c- p>)</c-> <c- c1>// dedicated worker</c->
  onmessage <c- o>=</c-> handleMessage<c- p>;</c->
<c- k>else</c-> <c- c1>// shared worker</c->
  onconnect <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c-> e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->onmessage <c- o>=</c-> handleMessage <c- p>};</c->
</code></pre>

  <p>The little subworkers would then be as follows.</p>

  <p>For generating key pairs:</p>

  <pre><code class='js'>onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> k <c- o>=</c-> _generateKeyPair<c- p>();</c->
  e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->postMessage<c- p>(</c->k<c- p>[</c-><c- mf>0</c-><c- p>]);</c->
  e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->postMessage<c- p>(</c->k<c- p>[</c-><c- mf>1</c-><c- p>]);</c->
  close<c- p>();</c->
<c- p>}</c->

<c- a>function</c-> _generateKeyPair<c- p>()</c-> <c- p>{</c->
  <c- k>return</c-> <c- p>[</c->Math<c- p>.</c->random<c- p>(),</c-> Math<c- p>.</c->random<c- p>()];</c->
<c- p>}</c->
</code></pre>

  <p>For encrypting:</p>

  <pre><code class='js'>onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> key <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
  e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    <c- a>var</c-> s <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
    postMessage<c- p>(</c->_encrypt<c- p>(</c->key<c- p>,</c-> s<c- p>));</c->
  <c- p>}</c->
<c- p>}</c->

<c- a>function</c-> _encrypt<c- p>(</c->k<c- p>,</c-> s<c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> <c- t>&apos;encrypted-&apos;</c-> <c- o>+</c-> k <c- o>+</c-> <c- t>&apos; &apos;</c-> <c- o>+</c-> s<c- p>;</c->
<c- p>}</c->
</code></pre>

  <p>For decrypting:</p>

  <pre><code class='js'>onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> key <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
  e<c- p>.</c->ports<c- p>[</c-><c- mf>0</c-><c- p>].</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->e<c- p>)</c-> <c- p>{</c->
    <c- a>var</c-> s <c- o>=</c-> e<c- p>.</c->data<c- p>;</c->
    postMessage<c- p>(</c->_decrypt<c- p>(</c->key<c- p>,</c-> s<c- p>));</c->
  <c- p>}</c->
<c- p>}</c->

<c- a>function</c-> _decrypt<c- p>(</c->k<c- p>,</c-> s<c- p>)</c-> <c- p>{</c->
  <c- k>return</c-> s<c- p>.</c->substr<c- p>(</c->s<c- p>.</c->indexOf<c- p>(</c-><c- t>&apos; &apos;</c-><c- p>)</c-><c- o>+</c-><c- mf>1</c-><c- p>);</c->
<c- p>}</c->
</code></pre>

  <p>Notice how the users of the API don't have to even know that this is happening — the API
  hasn't changed; the library can delegate to subworkers without changing its API, even though it is
  accepting data using message channels.</p>

  <p><a href=../demos/workers/crypto/page.html>View this example online</a>.</p>


  <h4 id=tutorials><span class=secno>10.1.3</span> Tutorials<a href=#tutorials class=self-link></a></h4>

  <h5 id=creating-a-dedicated-worker><span class=secno>10.1.3.1</span> Creating a dedicated worker<a href=#creating-a-dedicated-worker class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Creating a worker requires a URL to a JavaScript file. The <code id=creating-a-dedicated-worker:dom-worker><a href=#dom-worker>Worker()</a></code> constructor is invoked with the URL to that file as its only
  argument; a worker is then created and returned:</p>

  <pre><code class='js'><c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;helper.js&apos;</c-><c- p>);</c-></code></pre>

  <p>If you want your worker script to be interpreted as a <a id=creating-a-dedicated-worker:module-script href=webappapis.html#module-script>module script</a> instead of
  the default <a id=creating-a-dedicated-worker:classic-script href=webappapis.html#classic-script>classic script</a>, you need to use a slightly different signature:</p>

  <pre><code class='js'><c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> Worker<c- p>(</c-><c- t>&apos;helper.mjs&apos;</c-><c- p>,</c-> <c- p>{</c-> type<c- o>:</c-> <c- u>&quot;module&quot;</c-> <c- p>});</c-></code></pre>


  <h5 id=communicating-with-a-dedicated-worker><span class=secno>10.1.3.2</span> Communicating with a dedicated worker<a href=#communicating-with-a-dedicated-worker class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Dedicated workers use <code id=communicating-with-a-dedicated-worker:messageport><a href=web-messaging.html#messageport>MessagePort</a></code> objects behind the scenes, and thus support all
  the same features, such as sending structured data, transferring binary data, and transferring
  other ports.</p>

  <p>To receive messages from a dedicated worker, use the <code id=communicating-with-a-dedicated-worker:handler-messageeventtarget-onmessage><a href=web-messaging.html#handler-messageeventtarget-onmessage>onmessage</a></code> <a href=webappapis.html#event-handler-idl-attributes id=communicating-with-a-dedicated-worker:event-handler-idl-attributes>event handler IDL attribute</a> on the <code id=communicating-with-a-dedicated-worker:worker><a href=#worker>Worker</a></code> object:</p>

  <pre><code class='js'>worker<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>};</c-></code></pre>

  <p>You can also use the <code id=communicating-with-a-dedicated-worker:dom-eventtarget-addeventlistener><a data-x-internal=dom-eventtarget-addeventlistener href=https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener>addEventListener()</a></code>
  method.</p>

  <p class=note>The implicit <code id=communicating-with-a-dedicated-worker:messageport-2><a href=web-messaging.html#messageport>MessagePort</a></code> used by dedicated workers has its <a id=communicating-with-a-dedicated-worker:port-message-queue href=web-messaging.html#port-message-queue>port
  message queue</a> implicitly enabled when it is created, so there is no equivalent to the
  <code id=communicating-with-a-dedicated-worker:messageport-3><a href=web-messaging.html#messageport>MessagePort</a></code> interface's <code id=communicating-with-a-dedicated-worker:dom-messageport-start><a href=web-messaging.html#dom-messageport-start>start()</a></code> method on
  the <code id=communicating-with-a-dedicated-worker:worker-2><a href=#worker>Worker</a></code> interface.</p>

  <p>To <em>send</em> data to a worker, use the <code id=communicating-with-a-dedicated-worker:dom-worker-postmessage><a href=#dom-worker-postmessage>postMessage()</a></code> method. Structured data can be sent over this
  communication channel. To send <code id=communicating-with-a-dedicated-worker:idl-arraybuffer><a data-x-internal=idl-arraybuffer href=https://webidl.spec.whatwg.org/#idl-ArrayBuffer>ArrayBuffer</a></code> objects
  efficiently (by transferring them rather than cloning them), list them in an array in the second
  argument.</p>

  <pre><code class='js'>worker<c- p>.</c->postMessage<c- p>({</c->
  operation<c- o>:</c-> <c- t>&apos;find-edges&apos;</c-><c- p>,</c->
  input<c- o>:</c-> buffer<c- p>,</c-> <c- c1>// an ArrayBuffer object</c->
  threshold<c- o>:</c-> <c- mf>0.6</c-><c- p>,</c->
<c- p>},</c-> <c- p>[</c->buffer<c- p>]);</c-></code></pre>

  <p>To receive a message inside the worker, the <code id=communicating-with-a-dedicated-worker:handler-messageeventtarget-onmessage-2><a href=web-messaging.html#handler-messageeventtarget-onmessage>onmessage</a></code> <a href=webappapis.html#event-handler-idl-attributes id=communicating-with-a-dedicated-worker:event-handler-idl-attributes-2>event handler IDL attribute</a> is used.</p>

  <pre><code class='js'>onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>};</c-></code></pre>

  <p>You can again also use the <code id=communicating-with-a-dedicated-worker:dom-eventtarget-addeventlistener-2><a data-x-internal=dom-eventtarget-addeventlistener href=https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener>addEventListener()</a></code> method.</p>

  <p>In either case, the data is provided in the event object's <code id=communicating-with-a-dedicated-worker:dom-messageevent-data><a href=comms.html#dom-messageevent-data>data</a></code> attribute.</p>

  <p>To send messages back, you again use <code id=communicating-with-a-dedicated-worker:dom-dedicatedworkerglobalscope-postmessage><a href=#dom-dedicatedworkerglobalscope-postmessage>postMessage()</a></code>. It supports the
  structured data in the same manner.</p>

  <pre><code class='js'>postMessage<c- p>(</c->event<c- p>.</c->data<c- p>.</c->input<c- p>,</c-> <c- p>[</c->event<c- p>.</c->data<c- p>.</c->input<c- p>]);</c-> <c- c1>// transfer the buffer back</c-></code></pre>


  <h5 id=shared-workers data-dfn-type=dfn data-lt="shared worker"><span class=secno>10.1.3.3</span> Shared workers<a href=#shared-workers class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker title="The SharedWorker interface represents a specific kind of worker that can be accessed from several browsing contexts, such as several windows, iframes or even workers. They implement an interface different than dedicated workers and have a different global scope, SharedWorkerGlobalScope.">SharedWorker</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>33+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android no"><span>Chrome Android</span><span>No</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>4.0–5.0</span></span><span class="opera_android no"><span>Opera Android</span><span>11–14</span></span></div></div></div>

  <p><i>This section is non-normative.</i></p>

  <p>Shared workers are identified by the URL of the script used to create it, optionally with an
  explicit name. The name allows multiple instances of a particular shared worker to be started.</p>

  <p>Shared workers are scoped by <a id=shared-workers:concept-origin href=browsers.html#concept-origin>origin</a>. Two different sites using the same names will
  not collide. However, if a page tries to use the same shared worker name as another page on the
  same site, but with a different script URL, it will fail.</p>

  <p>Creating shared workers is done using the <code id=shared-workers:dom-sharedworker><a href=#dom-sharedworker>SharedWorker()</a></code>
  constructor. This constructor takes the URL to the script to use for its first argument, and the
  name of the worker, if any, as the second argument.</p>

  <pre><code class='js'><c- a>var</c-> worker <c- o>=</c-> <c- k>new</c-> SharedWorker<c- p>(</c-><c- t>&apos;service.js&apos;</c-><c- p>);</c-></code></pre>

  <p>Communicating with shared workers is done with explicit <code id=shared-workers:messageport><a href=web-messaging.html#messageport>MessagePort</a></code> objects. The
  object returned by the <code id=shared-workers:dom-sharedworker-2><a href=#dom-sharedworker>SharedWorker()</a></code> constructor holds a
  reference to the port on its <code id=shared-workers:dom-sharedworker-port><a href=#dom-sharedworker-port>port</a></code> attribute.</p>

  <pre><code class='js'>worker<c- p>.</c->port<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>};</c->
worker<c- p>.</c->port<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;some message&apos;</c-><c- p>);</c->
worker<c- p>.</c->port<c- p>.</c->postMessage<c- p>({</c-> foo<c- o>:</c-> <c- t>&apos;structured&apos;</c-><c- p>,</c-> bar<c- o>:</c-> <c- p>[</c-><c- t>&apos;data&apos;</c-><c- p>,</c-> <c- t>&apos;also&apos;</c-><c- p>,</c-> <c- t>&apos;possible&apos;</c-><c- p>]});</c-></code></pre>

  <p>Inside the shared worker, new clients of the worker are announced using the <code id=shared-workers:event-workerglobalscope-connect><a href=indices.html#event-workerglobalscope-connect>connect</a></code> event. The port for the new client is
  given by the event object's <code id=shared-workers:dom-messageevent-source><a href=comms.html#dom-messageevent-source>source</a></code> attribute.</p>

  <pre><code class='js'>onconnect <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c->
  <c- a>var</c-> newPort <c- o>=</c-> event<c- p>.</c->source<c- p>;</c->
  <c- c1>// set up a listener</c->
  newPort<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c-> <c- p>...</c-> <c- p>};</c->
  <c- c1>// send a message back to the port</c->
  newPort<c- p>.</c->postMessage<c- p>(</c-><c- t>&apos;ready!&apos;</c-><c- p>);</c-> <c- c1>// can also send structured data, of course</c->
<c- p>};</c-></code></pre>




  <h3 id=infrastructure-2><span class=secno>10.2</span> Infrastructure<a href=#infrastructure-2 class=self-link></a></h3>

  <p>This standard defines two kinds of workers: dedicated workers, and shared workers. Dedicated
  workers, once created, are linked to their creator, but message ports can be used to communicate
  from a dedicated worker to multiple other browsing contexts or workers. Shared workers, on the
  other hand, are named, and once created any script running in the same <a id=infrastructure-2:concept-origin href=browsers.html#concept-origin>origin</a> can
  obtain a reference to that worker and communicate with it. <cite>Service Workers</cite> defines a
  third kind. <a href=references.html#refsSW>[SW]</a></p>


  <h4 id=the-global-scope><span class=secno>10.2.1</span> The global scope<a href=#the-global-scope class=self-link></a></h4>

  <p>The global scope is the "inside" of a worker.</p>

  <h5 id=the-workerglobalscope-common-interface><span class=secno>10.2.1.1</span> The <code id=workerglobalscope-dev><a href=#workerglobalscope>WorkerGlobalScope</a></code> common interface<a href=#the-workerglobalscope-common-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope title="The WorkerGlobalScope interface of the Web Workers API is an interface representing the scope of any worker. Workers have no browsing context; this scope contains the information usually conveyed by Window objects — in this case event handlers, the console or the associated WorkerNavigator object. Each WorkerGlobalScope has its own event loop.">WorkerGlobalScope</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Worker</c->]
<c- b>interface</c-> <dfn id='workerglobalscope' data-dfn-type='interface'><c- g>WorkerGlobalScope</c-></dfn> : <a id='the-workerglobalscope-common-interface:eventtarget' href='https://dom.spec.whatwg.org/#interface-eventtarget' data-x-internal='eventtarget'><c- n>EventTarget</c-></a> {
  <c- b>readonly</c-> <c- b>attribute</c-> <a href='#workerglobalscope' id='the-workerglobalscope-common-interface:workerglobalscope'><c- n>WorkerGlobalScope</c-></a> <a href='#dom-workerglobalscope-self' id='the-workerglobalscope-common-interface:dom-workerglobalscope-self'><c- g>self</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <a href='#workerlocation' id='the-workerglobalscope-common-interface:workerlocation'><c- n>WorkerLocation</c-></a> <a href='#dom-workerglobalscope-location' id='the-workerglobalscope-common-interface:dom-workerglobalscope-location'><c- g>location</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <a href='#workernavigator' id='the-workerglobalscope-common-interface:workernavigator'><c- n>WorkerNavigator</c-></a> <a href='#dom-worker-navigator' id='the-workerglobalscope-common-interface:dom-worker-navigator'><c- g>navigator</c-></a>;
  <c- b>undefined</c-> <a href='#dom-workerglobalscope-importscripts' id='the-workerglobalscope-common-interface:dom-workerglobalscope-importscripts'><c- g>importScripts</c-></a>((<code id='the-workerglobalscope-common-interface:tt-trustedscripturl'><a data-x-internal='tt-trustedscripturl' href='https://w3c.github.io/trusted-types/dist/spec/#trustedscripturl'><c- n>TrustedScriptURL</c-></a></code> <c- b>or</c-> <c- b>USVString</c->)... <c- g>urls</c->);

  <c- b>attribute</c-> <a id='the-workerglobalscope-common-interface:onerroreventhandler' href='webappapis.html#onerroreventhandler'><c- n>OnErrorEventHandler</c-></a> <a href='#handler-workerglobalscope-onerror' id='the-workerglobalscope-common-interface:handler-workerglobalscope-onerror'><c- g>onerror</c-></a>;
  <c- b>attribute</c-> <a id='the-workerglobalscope-common-interface:eventhandler' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-workerglobalscope-onlanguagechange' id='the-workerglobalscope-common-interface:handler-workerglobalscope-onlanguagechange'><c- g>onlanguagechange</c-></a>;
  <c- b>attribute</c-> <a id='the-workerglobalscope-common-interface:eventhandler-2' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-workerglobalscope-onoffline' id='the-workerglobalscope-common-interface:handler-workerglobalscope-onoffline'><c- g>onoffline</c-></a>;
  <c- b>attribute</c-> <a id='the-workerglobalscope-common-interface:eventhandler-3' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-workerglobalscope-ononline' id='the-workerglobalscope-common-interface:handler-workerglobalscope-ononline'><c- g>ononline</c-></a>;
  <c- b>attribute</c-> <a id='the-workerglobalscope-common-interface:eventhandler-4' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-workerglobalscope-onrejectionhandled' id='the-workerglobalscope-common-interface:handler-workerglobalscope-onrejectionhandled'><c- g>onrejectionhandled</c-></a>;
  <c- b>attribute</c-> <a id='the-workerglobalscope-common-interface:eventhandler-5' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-workerglobalscope-onunhandledrejection' id='the-workerglobalscope-common-interface:handler-workerglobalscope-onunhandledrejection'><c- g>onunhandledrejection</c-></a>;
};</code></pre>

  <p><code id=the-workerglobalscope-common-interface:workerglobalscope-2><a href=#workerglobalscope>WorkerGlobalScope</a></code> serves as the base class for specific types of worker global
  scope objects, including <code id=the-workerglobalscope-common-interface:dedicatedworkerglobalscope><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code>,
  <code id=the-workerglobalscope-common-interface:sharedworkerglobalscope><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>, and <code id=the-workerglobalscope-common-interface:serviceworkerglobalscope><a data-x-internal=serviceworkerglobalscope href=https://w3c.github.io/ServiceWorker/#serviceworkerglobalscope>ServiceWorkerGlobalScope</a></code>.</p>

  

  <p id="the-worker's-documents">A <code id=the-workerglobalscope-common-interface:workerglobalscope-3><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-WorkerGlobalScope-owner-set data-export="">owner set</dfn> (a
  <a id=the-workerglobalscope-common-interface:set href=https://infra.spec.whatwg.org/#ordered-set data-x-internal=set>set</a> of <code id=the-workerglobalscope-common-interface:document><a href=dom.html#document>Document</a></code> and <code id=the-workerglobalscope-common-interface:workerglobalscope-4><a href=#workerglobalscope>WorkerGlobalScope</a></code> objects). It is
  initially empty and populated when the worker is created or obtained.</p>

  <p class=note>It is a <a id=the-workerglobalscope-common-interface:set-2 href=https://infra.spec.whatwg.org/#ordered-set data-x-internal=set>set</a>, instead of a single owner, to accommodate
  <code id=the-workerglobalscope-common-interface:sharedworkerglobalscope-2><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> objects.</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-5><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-type data-export="">type</dfn> ("<code>classic</code>" or "<code>module</code>"). It is set during creation.</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-6><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-url data-export="">url</dfn> (null or a <a id=the-workerglobalscope-common-interface:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a>). It is initially
  null.</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-7><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-name data-export="">name</dfn> (a string). It is set during creation.</p>

  <p class=note>The <a href=#concept-workerglobalscope-name id=the-workerglobalscope-common-interface:concept-workerglobalscope-name>name</a> can have different
  semantics for each subclass of <code id=the-workerglobalscope-common-interface:workerglobalscope-8><a href=#workerglobalscope>WorkerGlobalScope</a></code>. For
  <code id=the-workerglobalscope-common-interface:dedicatedworkerglobalscope-2><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> instances, it is simply a developer-supplied name, useful
  mostly for debugging purposes. For <code id=the-workerglobalscope-common-interface:sharedworkerglobalscope-3><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> instances, it allows
  obtaining a reference to a common shared worker via the <code id=the-workerglobalscope-common-interface:dom-sharedworker><a href=#dom-sharedworker>SharedWorker()</a></code> constructor. For
  <code id=the-workerglobalscope-common-interface:serviceworkerglobalscope-2><a data-x-internal=serviceworkerglobalscope href=https://w3c.github.io/ServiceWorker/#serviceworkerglobalscope>ServiceWorkerGlobalScope</a></code> objects, it doesn't make sense (and as such isn't exposed
  through the JavaScript API at all).</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-9><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-policy-container data-export="">policy container</dfn> (a <a id=the-workerglobalscope-common-interface:policy-container href=browsers.html#policy-container>policy
  container</a>). It is initially a new <a id=the-workerglobalscope-common-interface:policy-container-2 href=browsers.html#policy-container>policy container</a>.</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-10><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-embedder-policy data-export="">embedder policy</dfn> (an <a id=the-workerglobalscope-common-interface:embedder-policy href=browsers.html#embedder-policy>embedder
  policy</a>).</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-11><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-module-map data-export="">module map</dfn>.  It is a <a id=the-workerglobalscope-common-interface:module-map href=webappapis.html#module-map>module map</a>,
  initially empty.</p>

  <p>A <code id=the-workerglobalscope-common-interface:workerglobalscope-12><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has an associated <dfn data-dfn-for=WorkerGlobalScope id=concept-workerglobalscope-cross-origin-isolated-capability data-export="">cross-origin isolated
  capability</dfn> boolean. It is initially false.</p>

  

  <dl class=domintro><dt><code><var>workerGlobal</var>.<a href=#dom-workerglobalscope-self id=dom-workerglobalscope-self-dev>self</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/self title="The self read-only property of the WorkerGlobalScope interface returns a reference to the WorkerGlobalScope itself. Most of the time it is a specific scope like DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, or ServiceWorkerGlobalScope.">WorkerGlobalScope/self</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>11.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>34+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>Returns <var>workerGlobal</var>.<dt><code><var>workerGlobal</var>.<a href=#dom-workerglobalscope-location id=dom-workerglobalscope-location-dev>location</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/location title="The location read-only property of the WorkerGlobalScope interface returns the WorkerLocation associated with the worker. It is a specific location object, mostly a subset of the Location for browsing scopes, but adapted to workers.">WorkerGlobalScope/location</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>11.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>Returns <var>workerGlobal</var>'s <code id=the-workerglobalscope-common-interface:workerlocation-2><a href=#workerlocation>WorkerLocation</a></code> object.<dt><code><var>workerGlobal</var>.<a href=#dom-worker-navigator id=dom-worker-navigator-dev>navigator</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator title="The navigator read-only property of the WorkerGlobalScope interface returns the WorkerNavigator associated with the worker. It is a specific navigator object, mostly a subset of the Navigator for browsing scopes, but adapted to workers.">WorkerGlobalScope/navigator</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>11.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>17+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>Returns <var>workerGlobal</var>'s <code id=the-workerglobalscope-common-interface:workernavigator-2><a href=#workernavigator>WorkerNavigator</a></code> object.<dt><code><var>workerGlobal</var>.<a href=#dom-workerglobalscope-importscripts id=dom-workerglobalscope-importscripts-dev>importScripts</a>(...<var>urls</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts title="The importScripts() method of the WorkerGlobalScope interface synchronously imports one or more scripts into the worker's scope.">WorkerGlobalScope/importScripts</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>4+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd>Fetches each <a id=the-workerglobalscope-common-interface:url-2 href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a> in <var>urls</var>, executes them one-by-one in the order they
   are passed, and then returns (or throws if something went amiss).</dl>

  

  <p>The <dfn data-dfn-for=WorkerGlobalScope id=dom-workerglobalscope-self data-dfn-type=attribute><code>self</code></dfn> attribute must return the
  <code id=the-workerglobalscope-common-interface:workerglobalscope-13><a href=#workerglobalscope>WorkerGlobalScope</a></code> object itself.</p>

  <p>The <dfn data-dfn-for=WorkerGlobalScope id=dom-workerglobalscope-location data-dfn-type=attribute><code>location</code></dfn> attribute must return the
  <code id=the-workerglobalscope-common-interface:workerlocation-3><a href=#workerlocation>WorkerLocation</a></code> object whose associated <a href=#concept-workerlocation-workerglobalscope id=the-workerglobalscope-common-interface:concept-workerlocation-workerglobalscope><code>WorkerGlobalScope</code> object</a> is
  the <code id=the-workerglobalscope-common-interface:workerglobalscope-14><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</p>

  <p class=note>While the <code id=the-workerglobalscope-common-interface:workerlocation-4><a href=#workerlocation>WorkerLocation</a></code> object is created after the
  <code id=the-workerglobalscope-common-interface:workerglobalscope-15><a href=#workerglobalscope>WorkerGlobalScope</a></code> object, this is not problematic as it cannot be observed from
  script.</p>

  <hr>

  

  <p>The following are the <a id=the-workerglobalscope-common-interface:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <a href=webappapis.html#event-handler-event-type id=the-workerglobalscope-common-interface:event-handler-event-type>event handler event types</a>) that must be supported,
  as <a id=the-workerglobalscope-common-interface:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by objects implementing the
  <code id=the-workerglobalscope-common-interface:workerglobalscope-16><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface:</p>

  <table><thead><tr><th><a href=webappapis.html#event-handlers id=the-workerglobalscope-common-interface:event-handlers-2>Event handler</a> <th><a id=the-workerglobalscope-common-interface:event-handler-event-type-2 href=webappapis.html#event-handler-event-type>Event handler event type</a>
   <tbody><tr><td><dfn data-dfn-for=WorkerGlobalScope id=handler-workerglobalscope-onerror data-dfn-type=attribute><code>onerror</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/error_event title="The error event of the WorkerGlobalScope interface fires when an error occurs in the worker.">WorkerGlobalScope/error_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>11.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><td> <code id=the-workerglobalscope-common-interface:event-error><a href=indices.html#event-error>error</a></code>
    <tr><td><dfn data-dfn-for=WorkerGlobalScope id=handler-workerglobalscope-onlanguagechange data-dfn-type=attribute><code>onlanguagechange</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/languagechange_event title="The languagechange event is fired at the global scope object when the user's preferred language changes.">WorkerGlobalScope/languagechange_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>74+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>11.5+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><td> <code id=the-workerglobalscope-common-interface:event-languagechange><a href=indices.html#event-languagechange>languagechange</a></code> 
    <tr><td><dfn data-dfn-for=WorkerGlobalScope id=handler-workerglobalscope-onoffline data-dfn-type=attribute><code>onoffline</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/offline_event title="The offline event of the WorkerGlobalScope fires when the device loses connection to the internet.">WorkerGlobalScope/offline_event</a><div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>8+</span></span><span class="chrome no"><span>Chrome</span><span>No</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink no"><span>Edge</span><span>No</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><td> <code id=the-workerglobalscope-common-interface:event-offline><a href=indices.html#event-offline>offline</a></code> 
    <tr><td><dfn data-dfn-for=WorkerGlobalScope id=handler-workerglobalscope-ononline data-dfn-type=attribute><code>ononline</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/online_event title="The online event of the WorkerGlobalScope fires when the device reconnects to the internet.">WorkerGlobalScope/online_event</a><div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>8+</span></span><span class="chrome no"><span>Chrome</span><span>No</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink no"><span>Edge</span><span>No</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><td> <code id=the-workerglobalscope-common-interface:event-online><a href=indices.html#event-online>online</a></code> 
    <tr><td><dfn data-dfn-for=WorkerGlobalScope id=handler-workerglobalscope-onrejectionhandled data-dfn-type=attribute><code>onrejectionhandled</code></dfn> <td> <code id=the-workerglobalscope-common-interface:event-rejectionhandled><a href=indices.html#event-rejectionhandled>rejectionhandled</a></code>
    <tr><td><dfn data-dfn-for=WorkerGlobalScope id=handler-workerglobalscope-onunhandledrejection data-dfn-type=attribute><code>onunhandledrejection</code></dfn> <td> <code id=the-workerglobalscope-common-interface:event-unhandledrejection><a href=indices.html#event-unhandledrejection>unhandledrejection</a></code>
  </table>


  <h5 id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface><span class=secno>10.2.1.2</span> Dedicated workers and the <code id=dedicatedworkerglobalscope-dev><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> interface<a href=#dedicated-workers-and-the-dedicatedworkerglobalscope-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope title="The DedicatedWorkerGlobalScope object (the Worker global scope) is accessible through the self keyword. Some additional global functions, namespaces objects, and constructors, not typically associated with the worker global scope, but available on it, are listed in the JavaScript Reference. See also: Functions available to workers.">DedicatedWorkerGlobalScope</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <pre><code class='idl'>[<c- g>Global</c->=(<c- n>Worker</c->,<c- n>DedicatedWorker</c->),<c- g>Exposed</c->=<c- n>DedicatedWorker</c->]
<c- b>interface</c-> <dfn id='dedicatedworkerglobalscope' data-dfn-type='interface'><c- g>DedicatedWorkerGlobalScope</c-></dfn> : <a href='#workerglobalscope' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:workerglobalscope'><c- n>WorkerGlobalScope</c-></a> {
  [<c- g>Replaceable</c->] <c- b>readonly</c-> <c- b>attribute</c-> <c- b>DOMString</c-> <a href='#dom-dedicatedworkerglobalscope-name' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-dedicatedworkerglobalscope-name'><c- g>name</c-></a>;

  <c- b>undefined</c-> <a href='#dom-dedicatedworkerglobalscope-postmessage' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-dedicatedworkerglobalscope-postmessage'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->, <c- b>sequence</c->&lt;<a href='https://webidl.spec.whatwg.org/#idl-object' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:idl-object' data-x-internal='idl-object'><c- b>object</c-></a>&gt; <c- g>transfer</c->);
  <c- b>undefined</c-> <a href='#dom-dedicatedworkerglobalscope-postmessage-options' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-dedicatedworkerglobalscope-postmessage-options'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->, <c- b>optional</c-> <a id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:structuredserializeoptions' href='web-messaging.html#structuredserializeoptions'><c- n>StructuredSerializeOptions</c-></a> <c- g>options</c-> = {});

  <c- b>undefined</c-> <a href='#dom-dedicatedworkerglobalscope-close' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-dedicatedworkerglobalscope-close'><c- g>close</c-></a>();
};

<a href='#dedicatedworkerglobalscope' id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dedicatedworkerglobalscope'><c- n>DedicatedWorkerGlobalScope</c-></a> <c- b>includes</c-> <a id='dedicated-workers-and-the-dedicatedworkerglobalscope-interface:messageeventtarget' href='web-messaging.html#messageeventtarget'><c- n>MessageEventTarget</c-></a>;</code></pre>

  <p><code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dedicatedworkerglobalscope-2><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects have an associated <dfn id=inside-port>inside port</dfn> (a
  <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:messageport><a href=web-messaging.html#messageport>MessagePort</a></code>). This port is part of a channel that is set up when the worker is
  created, but it is not exposed. This object must never be garbage collected before
  the <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dedicatedworkerglobalscope-3><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</p>

  <dl class=domintro><dt><code><var>dedicatedWorkerGlobal</var>.<a href=#dom-dedicatedworkerglobalscope-name id=dom-dedicatedworkerglobalscope-name-dev>name</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/name title="The name read-only property of the DedicatedWorkerGlobalScope interface returns the name that the Worker was (optionally) given when it was created. This is the name that the Worker() constructor can pass to get a reference to the DedicatedWorkerGlobalScope.">DedicatedWorkerGlobalScope/name</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>55+</span></span><span class="safari yes"><span>Safari</span><span>12.1+</span></span><span class="chrome yes"><span>Chrome</span><span>70+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>18</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><p>Returns <var>dedicatedWorkerGlobal</var>'s <a href=#concept-workerglobalscope-name id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:concept-workerglobalscope-name>name</a>, i.e. the value given to the
   <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:worker><a href=#worker>Worker</a></code> constructor. Primarily useful for debugging.<dt><code><var>dedicatedWorkerGlobal</var>.<a href=#dom-dedicatedworkerglobalscope-postmessage id=dom-dedicatedworkerglobalscope-postmessage-dev>postMessage</a>(<var>message</var> [, <var>transfer</var> ])</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/postMessage title="The postMessage() method of the DedicatedWorkerGlobalScope interface sends a message to the main thread that spawned it.">DedicatedWorkerGlobalScope/postMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dt><code><var>dedicatedWorkerGlobal</var>.<a href=#dom-dedicatedworkerglobalscope-postmessage-options id=dom-dedicatedworkerglobalscope-postmessage-options-dev>postMessage</a>(<var>message</var> [, { <a href=web-messaging.html#dom-structuredserializeoptions-transfer id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-structuredserializeoptions-transfer>transfer</a> } ])</code><dd><p>Clones <var>message</var> and transmits it to the <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:worker-2><a href=#worker>Worker</a></code> object associated
   with <var>dedicatedWorkerGlobal</var>. <var>transfer</var> can be passed as a list of objects
   that are to be transferred rather than cloned.<dt><code><var>dedicatedWorkerGlobal</var>.<a href=#dom-dedicatedworkerglobalscope-close id=dom-dedicatedworkerglobalscope-close-dev>close</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope/close title="The close() method of the DedicatedWorkerGlobalScope interface discards any tasks queued in the DedicatedWorkerGlobalScope's event loop, effectively closing this particular scope.">DedicatedWorkerGlobalScope/close</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Aborts <var>dedicatedWorkerGlobal</var>.</dl>

  

  <p>The <dfn data-dfn-for=DedicatedWorkerGlobalScope id=dom-dedicatedworkerglobalscope-name data-dfn-type=attribute><code>name</code></dfn> getter steps are to return
  <a id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerglobalscope-name id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:concept-workerglobalscope-name-2>name</a>. Its value
  represents the name given to the worker using the <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:worker-3><a href=#worker>Worker</a></code> constructor, used primarily
  for debugging purposes.</p>

  <p>The <dfn data-dfn-for=DedicatedWorkerGlobalScope id=dom-dedicatedworkerglobalscope-postmessage data-dfn-type=method><code>postMessage(<var>message</var>,
  <var>transfer</var>)</code></dfn> and <dfn data-dfn-for=DedicatedWorkerGlobalScope id=dom-dedicatedworkerglobalscope-postmessage-options data-dfn-type=method><code>postMessage(<var>message</var>,
  <var>options</var>)</code></dfn> methods on <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dedicatedworkerglobalscope-4><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> objects act as
  if, when invoked, it immediately invoked the respective <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-messageport-postmessage><a href=web-messaging.html#dom-messageport-postmessage>postMessage(<var>message</var>, <var>transfer</var>)</a></code>
  and <code id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-messageport-postmessage-options><a href=web-messaging.html#dom-messageport-postmessage-options>postMessage(<var>message</var>,
  <var>options</var>)</a></code> on the port, with the same arguments, and returned the same return
  value.</p>

  <p>To <dfn id=close-a-worker data-export="">close a worker</dfn>, given a <var>workerGlobal</var>, run these steps:</p>

  <ol><li><p>Discard any <a href=webappapis.html#concept-task id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:concept-task>tasks</a> that have been added to
   <var>workerGlobal</var>'s <a id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:relevant-agent href=webappapis.html#relevant-agent>relevant agent</a>'s <a href=webappapis.html#concept-agent-event-loop id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:concept-agent-event-loop>event loop</a>'s <a href=webappapis.html#task-queue id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:task-queue>task
   queues</a>.</p>

   <li><p>Set <var>workerGlobal</var>'s <a href=#dom-workerglobalscope-closing id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:dom-workerglobalscope-closing>closing</a>
   flag to true. (This prevents any further tasks from being queued.)</ol>

  <p>The <dfn data-dfn-for=DedicatedWorkerGlobalScope id=dom-dedicatedworkerglobalscope-close data-dfn-type=method><code>close()</code></dfn> method steps are to
  <a href=#close-a-worker id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:close-a-worker>close a worker</a> given <a id=dedicated-workers-and-the-dedicatedworkerglobalscope-interface:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.</p>

  <hr>

  

  <h5 id=shared-workers-and-the-sharedworkerglobalscope-interface><span class=secno>10.2.1.3</span> Shared workers and the <code id=sharedworkerglobalscope-dev><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> interface<a href=#shared-workers-and-the-sharedworkerglobalscope-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorkerGlobalScope title="The SharedWorkerGlobalScope object (the SharedWorker global scope) is accessible through the self keyword. Some additional global functions, namespaces objects, and constructors, not typically associated with the worker global scope, but available on it, are listed in the JavaScript Reference. See the complete list of functions available to workers.">SharedWorkerGlobalScope</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <pre><code class='idl'>[<c- g>Global</c->=(<c- n>Worker</c->,<c- n>SharedWorker</c->),<c- g>Exposed</c->=<c- n>SharedWorker</c->]
<c- b>interface</c-> <dfn id='sharedworkerglobalscope' data-dfn-type='interface'><c- g>SharedWorkerGlobalScope</c-></dfn> : <a href='#workerglobalscope' id='shared-workers-and-the-sharedworkerglobalscope-interface:workerglobalscope'><c- n>WorkerGlobalScope</c-></a> {
  [<c- g>Replaceable</c->] <c- b>readonly</c-> <c- b>attribute</c-> <c- b>DOMString</c-> <a href='#dom-sharedworkerglobalscope-name' id='shared-workers-and-the-sharedworkerglobalscope-interface:dom-sharedworkerglobalscope-name'><c- g>name</c-></a>;

  <c- b>undefined</c-> <a href='#dom-sharedworkerglobalscope-close' id='shared-workers-and-the-sharedworkerglobalscope-interface:dom-sharedworkerglobalscope-close'><c- g>close</c-></a>();

  <c- b>attribute</c-> <a id='shared-workers-and-the-sharedworkerglobalscope-interface:eventhandler' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-sharedworkerglobalscope-onconnect' id='shared-workers-and-the-sharedworkerglobalscope-interface:handler-sharedworkerglobalscope-onconnect'><c- g>onconnect</c-></a>;
};</code></pre>

  

  <p>A <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworkerglobalscope><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object has associated <dfn id=concept-sharedworkerglobalscope-constructor-origin>constructor origin</dfn> (an
  <a id=shared-workers-and-the-sharedworkerglobalscope-interface:concept-origin href=browsers.html#concept-origin>origin</a>), <dfn id=concept-sharedworkerglobalscope-constructor-url>constructor
  URL</dfn> (a <a id=shared-workers-and-the-sharedworkerglobalscope-interface:url-record href=https://url.spec.whatwg.org/#concept-url data-x-internal=url-record>URL record</a>), and <dfn id=concept-sharedworkerglobalscope-credentials>credentials</dfn> (a <a href=https://fetch.spec.whatwg.org/#concept-request-credentials-mode id=shared-workers-and-the-sharedworkerglobalscope-interface:concept-request-credentials-mode data-x-internal=concept-request-credentials-mode>credentials mode</a>). They are initialized when the
  <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworkerglobalscope-2><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object is created, in the <a href=#run-a-worker id=shared-workers-and-the-sharedworkerglobalscope-interface:run-a-worker>run a worker</a>
  algorithm.</p>

  

  <p>Shared workers receive message ports through <code id=shared-workers-and-the-sharedworkerglobalscope-interface:event-workerglobalscope-connect><a href=indices.html#event-workerglobalscope-connect>connect</a></code> events on their <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworkerglobalscope-3><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object for each
  connection.</p>

  <dl class=domintro><dt><code><var>sharedWorkerGlobal</var>.<a href=#dom-sharedworkerglobalscope-name id=dom-sharedworkerglobalscope-name-dev>name</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorkerGlobalScope/name title="The name read-only property of the SharedWorkerGlobalScope interface returns the name that the SharedWorker was (optionally) given when it was created. This is the name that the SharedWorker() constructor can pass to get a reference to the SharedWorkerGlobalScope.">SharedWorkerGlobalScope/name</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Returns <var>sharedWorkerGlobal</var>'s <a href=#concept-workerglobalscope-name id=shared-workers-and-the-sharedworkerglobalscope-interface:concept-workerglobalscope-name>name</a>, i.e. the value given to the
   <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworker><a href=#sharedworker>SharedWorker</a></code> constructor. Multiple <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworker-2><a href=#sharedworker>SharedWorker</a></code> objects can correspond
   to the same shared worker (and <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworkerglobalscope-4><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>), by reusing the same
   name.<dt><code><var>sharedWorkerGlobal</var>.<a href=#dom-sharedworkerglobalscope-close id=dom-sharedworkerglobalscope-close-dev>close</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorkerGlobalScope/close title="The close() method of the SharedWorkerGlobalScope interface discards any tasks queued in the SharedWorkerGlobalScope's event loop, effectively closing this particular scope.">SharedWorkerGlobalScope/close</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd><p>Aborts <var>sharedWorkerGlobal</var>.</dl>

  

  <p>The <dfn data-dfn-for=SharedWorkerGlobalScope id=dom-sharedworkerglobalscope-name data-dfn-type=attribute><code>name</code></dfn> getter steps are to return
  <a id=shared-workers-and-the-sharedworkerglobalscope-interface:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerglobalscope-name id=shared-workers-and-the-sharedworkerglobalscope-interface:concept-workerglobalscope-name-2>name</a>. Its value
  represents the name that can be used to obtain a reference to the worker using the
  <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworker-3><a href=#sharedworker>SharedWorker</a></code> constructor.</p>

  <p>The <dfn data-dfn-for=SharedWorkerGlobalScope id=dom-sharedworkerglobalscope-close data-dfn-type=method><code>close()</code></dfn> method steps are to <a href=#close-a-worker id=shared-workers-and-the-sharedworkerglobalscope-interface:close-a-worker>close a
  worker</a> given <a id=shared-workers-and-the-sharedworkerglobalscope-interface:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.</p>

  <hr>

  

  <p>The following are the <a id=shared-workers-and-the-sharedworkerglobalscope-interface:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <a href=webappapis.html#event-handler-event-type id=shared-workers-and-the-sharedworkerglobalscope-interface:event-handler-event-type>event handler event types</a>) that must be supported,
  as <a id=shared-workers-and-the-sharedworkerglobalscope-interface:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by objects implementing the
  <code id=shared-workers-and-the-sharedworkerglobalscope-interface:sharedworkerglobalscope-5><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> interface:</p>

  <table><thead><tr><th><a href=webappapis.html#event-handlers id=shared-workers-and-the-sharedworkerglobalscope-interface:event-handlers-2>Event handler</a> <th><a id=shared-workers-and-the-sharedworkerglobalscope-interface:event-handler-event-type-2 href=webappapis.html#event-handler-event-type>Event handler event type</a>
   <tbody><tr><td><dfn data-dfn-for=SharedWorkerGlobalScope id=handler-sharedworkerglobalscope-onconnect data-dfn-type=attribute><code>onconnect</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorkerGlobalScope/connect_event title="The connect event is fired in shared workers at their SharedWorkerGlobalScope when a new client connects.">SharedWorkerGlobalScope/connect_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><td> <code id=shared-workers-and-the-sharedworkerglobalscope-interface:event-workerglobalscope-connect-2><a href=indices.html#event-workerglobalscope-connect>connect</a></code>
  </table>



  <h4 id=worker-event-loop><span class=secno>10.2.2</span> The event loop<a href=#worker-event-loop class=self-link></a></h4>

  <p>A <a id=worker-event-loop:worker-event-loop-2 href=webappapis.html#worker-event-loop-2>worker event loop</a>'s <a href=webappapis.html#task-queue id=worker-event-loop:task-queue>task queues</a> only have
  events, callbacks, and networking activity as <a href=webappapis.html#concept-task id=worker-event-loop:concept-task>tasks</a>. These <a href=webappapis.html#worker-event-loop-2 id=worker-event-loop:worker-event-loop-2-2>worker event loops</a> are created by the
  <a href=#run-a-worker id=worker-event-loop:run-a-worker>run a worker</a> algorithm.</p>

  <p>Each <code id=worker-event-loop:workerglobalscope><a href=#workerglobalscope>WorkerGlobalScope</a></code> object has a <dfn data-dfn-for=WorkerGlobalScope id=dom-workerglobalscope-closing data-export="">closing</dfn> flag, which must be initially
  false, but which can get set to true by the algorithms in the processing model
  section below.</p>

  <p>Once the <code id=worker-event-loop:workerglobalscope-2><a href=#workerglobalscope>WorkerGlobalScope</a></code>'s <a href=#dom-workerglobalscope-closing id=worker-event-loop:dom-workerglobalscope-closing>closing</a> flag is set to true, the <a id=worker-event-loop:event-loop href=webappapis.html#event-loop>event
  loop</a>'s <a href=webappapis.html#task-queue id=worker-event-loop:task-queue-2>task queues</a> must discard any
  further <a href=webappapis.html#concept-task id=worker-event-loop:concept-task-2>tasks</a> that would be added to them (tasks already on the
  queue are unaffected except where otherwise specified). Effectively, once the <a href=#dom-workerglobalscope-closing id=worker-event-loop:dom-workerglobalscope-closing-2>closing</a> flag is true, timers stop firing,
  notifications for all pending background operations are dropped, etc.</p>



  

  <h4 id="the-worker's-lifetime"><span class=secno>10.2.3</span> The worker's lifetime<a href="#the-worker's-lifetime" class=self-link></a></h4>

  <p>Workers communicate with other workers and with <code id="the-worker's-lifetime:window"><a href=nav-history-apis.html#window>Window</a></code>s through <a href=web-messaging.html#channel-messaging id="the-worker's-lifetime:channel-messaging">message channels</a> and their <code id="the-worker's-lifetime:messageport"><a href=web-messaging.html#messageport>MessagePort</a></code>
  objects.</p>

  <p>Each <code id="the-worker's-lifetime:workerglobalscope"><a href=#workerglobalscope>WorkerGlobalScope</a></code> object <var>worker global scope</var> has a list of
  <dfn id="the-worker's-ports" data-export="">the worker's ports</dfn>, which consists of all the <code id="the-worker's-lifetime:messageport-2"><a href=web-messaging.html#messageport>MessagePort</a></code> objects
  that are entangled with another port and that have one (but only one) port owned by <var>worker
  global scope</var>. This list includes the implicit <code id="the-worker's-lifetime:messageport-3"><a href=web-messaging.html#messageport>MessagePort</a></code> in the case of <a href=#dedicatedworkerglobalscope id="the-worker's-lifetime:dedicatedworkerglobalscope">dedicated workers</a>.</p>

  <p id=list-of-relevant-document-objects-to-add>Given an <a id="the-worker's-lifetime:environment-settings-object" href=webappapis.html#environment-settings-object>environment settings
  object</a> <var>o</var> when creating or obtaining a worker, the <dfn id=relevant-owner-to-add>relevant owner to
  add</dfn> depends on the type of <a href=webappapis.html#concept-settings-object-global id="the-worker's-lifetime:concept-settings-object-global">global
  object</a> specified by <var>o</var>. If <var>o</var>'s <a href=webappapis.html#concept-settings-object-global id="the-worker's-lifetime:concept-settings-object-global-2">global object</a> is a <code id="the-worker's-lifetime:workerglobalscope-2"><a href=#workerglobalscope>WorkerGlobalScope</a></code>
  object (i.e., if we are creating a nested dedicated worker), then the relevant owner is that
  global object. Otherwise, <var>o</var>'s <a href=webappapis.html#concept-settings-object-global id="the-worker's-lifetime:concept-settings-object-global-3">global
  object</a> is a <code id="the-worker's-lifetime:window-2"><a href=nav-history-apis.html#window>Window</a></code> object, and the relevant owner is that
  <code id="the-worker's-lifetime:window-3"><a href=nav-history-apis.html#window>Window</a></code>'s <a href=nav-history-apis.html#concept-document-window id="the-worker's-lifetime:concept-document-window">associated
  <code>Document</code></a>.</p>

  <hr>

  <p>A user agent has an <a id="the-worker's-lifetime:implementation-defined" href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a> value, the <dfn id=between-loads-shared-worker-timeout>between-loads shared
  worker timeout</dfn>, which is some small amount of time. This represents how long the user agent
  allows shared workers to survive while a page is loading, in case that page is going to contact
  the shared worker again. Setting this value to greater than zero lets user agents avoid the cost
  of restarting a shared worker used by a site when the user is navigating from page to page within
  that site.</p>

  <p class=note>A typical value for the <a href=#between-loads-shared-worker-timeout id="the-worker's-lifetime:between-loads-shared-worker-timeout">between-loads shared worker timeout</a> might be
  5 seconds.</p>

  <hr>

  <p>A <code id="the-worker's-lifetime:workerglobalscope-3"><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var>global</var> is <dfn id=active-needed-worker>actively needed</dfn> if the following algorithm returns true:</p>

  <ol><li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id="the-worker's-lifetime:list-iterate" data-x-internal=list-iterate>For each</a> <var>owner</var> of <var>global</var>'s
    <a href=#concept-WorkerGlobalScope-owner-set id="the-worker's-lifetime:concept-WorkerGlobalScope-owner-set">owner set</a>:</p>

    <ol><li><p>If <var>owner</var> is a <code id="the-worker's-lifetime:document"><a href=dom.html#document>Document</a></code>, and <var>owner</var> is <a id="the-worker's-lifetime:fully-active" href=document-sequences.html#fully-active>fully
     active</a>, then return true.<li><p>If <var>owner</var> is a <code id="the-worker's-lifetime:workerglobalscope-4"><a href=#workerglobalscope>WorkerGlobalScope</a></code> that is <a href=#active-needed-worker id="the-worker's-lifetime:active-needed-worker">actively needed</a>, then return true.</ol>
   <li><p>Return false.</ol>

  <p>A <code id="the-worker's-lifetime:workerglobalscope-5"><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var>global</var> is <dfn id=protected-worker>protected</dfn> if the following algorithm returns true:</p>

  <ol><li><p>If <var>global</var> is not <a href=#active-needed-worker id="the-worker's-lifetime:active-needed-worker-2">actively needed</a>,
   then return false.<li><p>If <var>global</var> is a <code id="the-worker's-lifetime:sharedworkerglobalscope"><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>, then return true.<li><p>If <var>global</var>'s <a href="#the-worker's-ports" id="the-worker's-lifetime:the-worker's-ports">the worker's ports</a> is not <a href=https://infra.spec.whatwg.org/#list-is-empty id="the-worker's-lifetime:list-is-empty" data-x-internal=list-is-empty>empty</a>, then return true.<li><p>If <var>global</var> has outstanding timers, database transactions, or network
   connections, then return true.<li><p>Return false.</ol>

  <p>A <code id="the-worker's-lifetime:workerglobalscope-6"><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var>global</var> is <dfn id=permissible-worker>permissible</dfn> if the following algorithm returns true:</p>

  <ol><li><p>If <var>global</var>'s <a href=#concept-WorkerGlobalScope-owner-set id="the-worker's-lifetime:concept-WorkerGlobalScope-owner-set-2">owner set</a> is not <a href=https://infra.spec.whatwg.org/#list-is-empty id="the-worker's-lifetime:list-is-empty-2" data-x-internal=list-is-empty>empty</a>, then return true.<li>
    <p>If all of the following are true:</p>

    <ul><li><p><var>global</var> is a <code id="the-worker's-lifetime:sharedworkerglobalscope-2"><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code>;<li><p><var>global</var>'s <a href=#concept-WorkerGlobalScope-owner-set id="the-worker's-lifetime:concept-WorkerGlobalScope-owner-set-3">owner set</a> has been <a href=https://infra.spec.whatwg.org/#list-is-empty id="the-worker's-lifetime:list-is-empty-3" data-x-internal=list-is-empty>empty</a> for no more than the user agent's <a href=#between-loads-shared-worker-timeout id="the-worker's-lifetime:between-loads-shared-worker-timeout-2">between-loads shared worker
     timeout</a>; and</p>

     <li><p>the user agent has a <a id="the-worker's-lifetime:navigable" href=document-sequences.html#navigable>navigable</a> whose <a href=document-sequences.html#nav-document id="the-worker's-lifetime:nav-document">active
     document</a> is not <a id="the-worker's-lifetime:completely-loaded" href=document-lifecycle.html#completely-loaded>completely loaded</a>,</ul>

    <p>then return true.</p>
   <li><p>Return false.</ol>

  <p>A <code id="the-worker's-lifetime:workerglobalscope-7"><a href=#workerglobalscope>WorkerGlobalScope</a></code> <var>global</var> is <dfn id=suspendable-worker>suspendable</dfn> if the following algorithm returns true:</p>

  <ol><li><p>If <var>global</var> is <a href=#active-needed-worker id="the-worker's-lifetime:active-needed-worker-3">actively needed</a>, then
   return false.<li><p>If <var>global</var> is <a href=#permissible-worker id="the-worker's-lifetime:permissible-worker">permissible</a>, then return
   true.<li><p>Return false.</ol>

  <div id=note-worker-lifetime-terminology class=note><a href=#note-worker-lifetime-terminology class=self-link></a>
   <p>These concepts are used elsewhere in the specification's normative requirements as
   follows:</p>

   <ul><li><p>Workers get <a href=#step-closing-orphan-workers>closed as orphans</a> between when
    they stop being <a href=#protected-worker id="the-worker's-lifetime:protected-worker">protected</a> and when they stop being <a href=#permissible-worker id="the-worker's-lifetime:permissible-worker-2">permissible</a>.<li><p>Workers get <a href=#step-suspending-workers>suspended or un-suspended</a> based on
    whether they are <a href=#suspendable-worker id="the-worker's-lifetime:suspendable-worker">suspendable</a>.<li><p>Workers that have been closed, but keep executing, <a href=#terminate-rampant-workers>can be terminated</a> at the user agent's discretion, once
    they stop being <a href=#active-needed-worker id="the-worker's-lifetime:active-needed-worker-4">actively needed</a>.</ul>

   <p>Note that every <code id="the-worker's-lifetime:workerglobalscope-8"><a href=#workerglobalscope>WorkerGlobalScope</a></code> that is <a href=#active-needed-worker id="the-worker's-lifetime:active-needed-worker-5">actively needed</a> is <a href=#protected-worker id="the-worker's-lifetime:protected-worker-2">protected</a>, and every
   <code id="the-worker's-lifetime:workerglobalscope-9"><a href=#workerglobalscope>WorkerGlobalScope</a></code> that is <a href=#protected-worker id="the-worker's-lifetime:protected-worker-3">protected</a> is <a href=#permissible-worker id="the-worker's-lifetime:permissible-worker-3">permissible</a>. (But the converses do not hold.)</p>

   <p>An important difference between <a href=#protected-worker id="the-worker's-lifetime:protected-worker-4">protected</a> and <a href=#permissible-worker id="the-worker's-lifetime:permissible-worker-4">permissible</a> is that a <code id="the-worker's-lifetime:workerglobalscope-10"><a href=#workerglobalscope>WorkerGlobalScope</a></code> is <a href=#protected-worker id="the-worker's-lifetime:protected-worker-5">protected</a> only if its transitive set of owners contains at least
   one <a id="the-worker's-lifetime:fully-active-2" href=document-sequences.html#fully-active>fully active</a> <code id="the-worker's-lifetime:document-2"><a href=dom.html#document>Document</a></code>, whereas a <code id="the-worker's-lifetime:workerglobalscope-11"><a href=#workerglobalscope>WorkerGlobalScope</a></code> can
   be <a href=#permissible-worker id="the-worker's-lifetime:permissible-worker-5">permissible</a> even if all the <code id="the-worker's-lifetime:document-3"><a href=dom.html#document>Document</a></code>s in
   its transitive set of owners are in <a href=browsing-the-web.html#note-bfcache>bfcache</a>.</p>
  </div>

  <p id=note-between-loads-shared-worker-timeout-lifetime class=note><a href=#note-between-loads-shared-worker-timeout-lifetime class=self-link></a>The <a href=#between-loads-shared-worker-timeout id="the-worker's-lifetime:between-loads-shared-worker-timeout-3">between-loads
  shared worker timeout</a> only influences the definition of <a href=#permissible-worker id="the-worker's-lifetime:permissible-worker-6">permissible</a>, not <a href=#protected-worker id="the-worker's-lifetime:protected-worker-6">protected</a>, and so
  implementations are not required to keep shared workers alive for that duration. Rather, they are
  required to close shared workers after the timeout is reached.</p>


  <h4 id=worker-processing-model><span class=secno>10.2.4</span> <span id=processing-model-10></span>Processing model<a href=#worker-processing-model class=self-link></a></h4>

  <p>When a user agent is to <dfn id=run-a-worker data-export="">run a worker</dfn> for a script with <code id=worker-processing-model:worker><a href=#worker>Worker</a></code> or
  <code id=worker-processing-model:sharedworker><a href=#sharedworker>SharedWorker</a></code> object <var>worker</var>, <a id=worker-processing-model:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>URL</a> <var>url</var>,
  <a id=worker-processing-model:environment-settings-object href=webappapis.html#environment-settings-object>environment settings object</a> <var>outside settings</var>, <code id=worker-processing-model:messageport><a href=web-messaging.html#messageport>MessagePort</a></code>
  <var>outside port</var>, and a <code id=worker-processing-model:workeroptions><a href=#workeroptions>WorkerOptions</a></code> dictionary <var>options</var>, it must
  run the following steps.</p>

  <ol><li><p>Let <var>is shared</var> be true if <var>worker</var> is a <code id=worker-processing-model:sharedworker-2><a href=#sharedworker>SharedWorker</a></code>
   object, and false otherwise.<li><p>Let <var>owner</var> be the <a href=#relevant-owner-to-add id=worker-processing-model:relevant-owner-to-add>relevant owner to add</a> given <var>outside
   settings</var>.<li><p>Let <var>unsafeWorkerCreationTime</var> be the <a id=worker-processing-model:unsafe-shared-current-time href=https://w3c.github.io/hr-time/#dfn-unsafe-shared-current-time data-x-internal=unsafe-shared-current-time>unsafe shared current
   time</a>.<li><p>Let <var>agent</var> be the result of <a href=webappapis.html#obtain-a-dedicated/shared-worker-agent id=worker-processing-model:obtain-a-dedicated/shared-worker-agent>obtaining a dedicated/shared worker agent</a> given <var>outside settings</var> and
   <var>is shared</var>. Run the rest of these steps in that agent.<li>
    <p>Let <var>realm execution context</var> be the result of <a id=worker-processing-model:creating-a-new-javascript-realm href=webappapis.html#creating-a-new-javascript-realm>creating a new realm</a>
    given <var>agent</var> and the following customizations:</p>

    <ul><li><p>For the global object, if <var>is shared</var> is true, create a new
     <code id=worker-processing-model:sharedworkerglobalscope><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object. Otherwise, create a new
     <code id=worker-processing-model:dedicatedworkerglobalscope><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object.</ul>
   <li>
    <p>Let <var>worker global scope</var> be the <a href=webappapis.html#concept-realm-global id=worker-processing-model:concept-realm-global>global
    object</a> of <var>realm execution context</var>'s Realm component.

    <p class=note>This is the <code id=worker-processing-model:dedicatedworkerglobalscope-2><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> or
    <code id=worker-processing-model:sharedworkerglobalscope-2><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object created in the previous step.</p>
   <li><p><a href=#set-up-a-worker-environment-settings-object id=worker-processing-model:set-up-a-worker-environment-settings-object>Set up a worker environment settings object</a> with <var>realm execution
   context</var>, <var>outside settings</var>, and <var>unsafeWorkerCreationTime</var>, and let
   <var>inside settings</var> be the result.<li><p>Set <var>worker global scope</var>'s <a href=#concept-workerglobalscope-name id=worker-processing-model:concept-workerglobalscope-name>name</a> to <var>options</var>["<code id=worker-processing-model:dom-workeroptions-name><a href=#dom-workeroptions-name>name</a></code>"].<li><p><a href=https://infra.spec.whatwg.org/#set-append id=worker-processing-model:set-append data-x-internal=set-append>Append</a> <var>owner</var> to <var>worker global
   scope</var>'s <a href=#concept-WorkerGlobalScope-owner-set id=worker-processing-model:concept-WorkerGlobalScope-owner-set>owner set</a>.<li>
    <p>If <var>is shared</var> is true, then:</p>

    <ol><li><p>Set <var>worker global scope</var>'s <a href=#concept-sharedworkerglobalscope-constructor-origin id=worker-processing-model:concept-sharedworkerglobalscope-constructor-origin>constructor origin</a> to
     <var>outside settings</var>'s <a href=webappapis.html#concept-settings-object-origin id=worker-processing-model:concept-settings-object-origin>origin</a>.<li><p>Set <var>worker global scope</var>'s <a href=#concept-sharedworkerglobalscope-constructor-url id=worker-processing-model:concept-sharedworkerglobalscope-constructor-url>constructor URL</a> to
     <var>url</var>.<li><p>Set <var>worker global scope</var>'s <a href=#concept-workerglobalscope-type id=worker-processing-model:concept-workerglobalscope-type>type</a> to <var>options</var>["<code id=worker-processing-model:dom-workeroptions-type><a href=#dom-workeroptions-type>type</a></code>"].<li><p>Set <var>worker global scope</var>'s <a href=#concept-sharedworkerglobalscope-credentials id=worker-processing-model:concept-sharedworkerglobalscope-credentials>credentials</a> to
     <var>options</var>["<code id=worker-processing-model:dom-workeroptions-credentials><a href=#dom-workeroptions-credentials>credentials</a></code>"].</ol>
   <li><p>Let <var>destination</var> be "<code>sharedworker</code>" if <var>is
   shared</var> is true, and "<code>worker</code>" otherwise.<li>
    <p>Obtain <var>script</var> by switching on <var>options</var>["<code id=worker-processing-model:dom-workeroptions-type-2><a href=#dom-workeroptions-type>type</a></code>"]:</p>

    <dl class=switch><dt>"<code>classic</code>"<dd><a id=worker-processing-model:fetch-a-classic-worker-script href=webappapis.html#fetch-a-classic-worker-script>Fetch a classic worker script</a> given <var>url</var>, <var>outside
     settings</var>, <var>destination</var>, <var>inside settings</var>, and with
     <var>onComplete</var> and <var>performFetch</var> as defined below.<dt>"<code>module</code>"<dd><a id=worker-processing-model:fetch-a-module-worker-script-tree href=webappapis.html#fetch-a-module-worker-script-tree>Fetch a module worker script graph</a> given <var>url</var>, <var>outside
     settings</var>, <var>destination</var>, the value of the <code>credentials</code>
     member of <var>options</var>, <var>inside settings</var>, and with <var>onComplete</var> and
     <var>performFetch</var> as defined below.</dl>

    <p>In both cases, let <var>performFetch</var> be the following <a href=webappapis.html#fetching-scripts-perform-fetch id=worker-processing-model:fetching-scripts-perform-fetch>perform the fetch hook</a> given <var>request</var>,
    <var id=worker-processing-model:fetching-scripts-is-top-level><a href=webappapis.html#fetching-scripts-is-top-level>isTopLevel</a></var>, and <var id=worker-processing-model:fetching-scripts-processcustomfetchresponse><a href=webappapis.html#fetching-scripts-processcustomfetchresponse>processCustomFetchResponse</a></var>:</p>

    <ol><li><p>If <var>isTopLevel</var> is false, <a href=https://fetch.spec.whatwg.org/#concept-fetch id=worker-processing-model:concept-fetch data-x-internal=concept-fetch>fetch</a>
     <var>request</var> with <i id=worker-processing-model:processresponseconsumebody><a data-x-internal=processresponseconsumebody href=https://fetch.spec.whatwg.org/#process-response-end-of-body>processResponseConsumeBody</a></i>
     set to <var>processCustomFetchResponse</var>, and abort these steps.<li>Set <var>request</var>'s <a href=https://fetch.spec.whatwg.org/#concept-request-reserved-client id=worker-processing-model:concept-request-reserved-client data-x-internal=concept-request-reserved-client>reserved
     client</a> to <var>inside settings</var>.<li>
      <p><a href=https://fetch.spec.whatwg.org/#concept-fetch id=worker-processing-model:concept-fetch-2 data-x-internal=concept-fetch>Fetch</a> <var>request</var> with <i id=worker-processing-model:processresponseconsumebody-2><a data-x-internal=processresponseconsumebody href=https://fetch.spec.whatwg.org/#process-response-end-of-body>processResponseConsumeBody</a></i> set to the following steps
      given <a href=https://fetch.spec.whatwg.org/#concept-response id=worker-processing-model:concept-response data-x-internal=concept-response>response</a> <var>response</var> and null, failure,
      or a <a id=worker-processing-model:byte-sequence href=https://infra.spec.whatwg.org/#byte-sequence data-x-internal=byte-sequence>byte sequence</a> <var>bodyBytes</var>:</p>

      <ol><li><p>Set <var>worker global scope</var>'s <a href=#concept-workerglobalscope-url id=worker-processing-model:concept-workerglobalscope-url>url</a> to <var>response</var>'s <a href=https://fetch.spec.whatwg.org/#concept-response-url id=worker-processing-model:concept-response-url data-x-internal=concept-response-url>url</a>.<li><p><a href=browsers.html#initialize-worker-policy-container id=worker-processing-model:initialize-worker-policy-container>Initialize worker global scope's
       policy container</a> given <var>worker global scope</var>, <var>response</var>, and
       <var>inside settings</var>.<li><p>If the <a id=worker-processing-model:run-csp-initialization-for-a-global-object href=https://w3c.github.io/webappsec-csp/#run-global-object-csp-initialization data-x-internal=run-csp-initialization-for-a-global-object>Run CSP initialization for a global object</a> algorithm returns
       "<code>Blocked</code>" when executed upon <var>worker global scope</var>, set
       <var>response</var> to a <a id=worker-processing-model:network-error href=https://fetch.spec.whatwg.org/#concept-network-error data-x-internal=network-error>network error</a>. <a href=references.html#refsCSP>[CSP]</a><li>
        <p>If <var>worker global scope</var>'s <a href=#concept-workerglobalscope-embedder-policy id=worker-processing-model:concept-workerglobalscope-embedder-policy>embedder policy</a>'s <a href=browsers.html#embedder-policy-value-2 id=worker-processing-model:embedder-policy-value-2>value</a> is <a id=worker-processing-model:compatible-with-cross-origin-isolation href=browsers.html#compatible-with-cross-origin-isolation>compatible with cross-origin
        isolation</a> and <var>is shared</var> is true, then set <var>agent</var>'s <a id=worker-processing-model:agent-cluster href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent
        cluster</a>'s <a href=webappapis.html#agent-cluster-cross-origin-isolation id=worker-processing-model:agent-cluster-cross-origin-isolation>cross-origin isolation
        mode</a> to "<code id=worker-processing-model:cross-origin-isolation-logical><a href=document-sequences.html#cross-origin-isolation-logical>logical</a></code>" or "<code id=worker-processing-model:cross-origin-isolation-concrete><a href=document-sequences.html#cross-origin-isolation-concrete>concrete</a></code>". The one chosen is
        <a id=worker-processing-model:implementation-defined href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a>.</p>

        <p class=XXX>This really ought to be set when the agent cluster is created, which requires
        a redesign of this section.</p>
       <li><p>If the result of <a href="browsers.html#check-a-global-object's-embedder-policy" id="worker-processing-model:check-a-global-object's-embedder-policy">checking a
       global object's embedder policy</a> with <var>worker global scope</var>, <var>outside
       settings</var>, and <var>response</var> is false, then set <var>response</var> to a
       <a id=worker-processing-model:network-error-2 href=https://fetch.spec.whatwg.org/#concept-network-error data-x-internal=network-error>network error</a>.<li><p>Set <var>worker global scope</var>'s <a href=#concept-workerglobalscope-cross-origin-isolated-capability id=worker-processing-model:concept-workerglobalscope-cross-origin-isolated-capability>cross-origin isolated
       capability</a> to true if <var>agent</var>'s <a id=worker-processing-model:agent-cluster-2 href=https://tc39.es/ecma262/#sec-agent-clusters data-x-internal=agent-cluster>agent cluster</a>'s <a href=webappapis.html#agent-cluster-cross-origin-isolation id=worker-processing-model:agent-cluster-cross-origin-isolation-2>cross-origin isolation mode</a> is "<code id=worker-processing-model:cross-origin-isolation-concrete-2><a href=document-sequences.html#cross-origin-isolation-concrete>concrete</a></code>".<li><p>If <var>is shared</var> is false and <var>owner</var>'s <a href=webappapis.html#concept-settings-object-cross-origin-isolated-capability id=worker-processing-model:concept-settings-object-cross-origin-isolated-capability>cross-origin isolated
       capability</a> is false, then set <var>worker global scope</var>'s <a href=#concept-workerglobalscope-cross-origin-isolated-capability id=worker-processing-model:concept-workerglobalscope-cross-origin-isolated-capability-2>cross-origin isolated
       capability</a> to false.<li>
        <p>If <var>is shared</var> is false and <var>response</var>'s
        <a href=https://fetch.spec.whatwg.org/#concept-response-url id=worker-processing-model:concept-response-url-2 data-x-internal=concept-response-url>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-scheme id=worker-processing-model:concept-url-scheme data-x-internal=concept-url-scheme>scheme</a> is "<code>data</code>", then set
        <var>worker global scope</var>'s <a href=#concept-workerglobalscope-cross-origin-isolated-capability id=worker-processing-model:concept-workerglobalscope-cross-origin-isolated-capability-3>cross-origin isolated
        capability</a> to false.</p>

        <p class=note>This is a conservative default for now, while we figure out how workers in
        general, and <code id=worker-processing-model:data-protocol><a data-x-internal=data-protocol href=https://www.rfc-editor.org/rfc/rfc2397#section-2>data:</a></code> URL workers in particular (which are
        cross-origin from their owner), will be treated in the context of permissions policies. See
        <a href=https://github.com/w3c/webappsec-permissions-policy/issues/207>w3c/webappsec-permissions-policy
        issue #207</a> for more details.</p>
       <li><p>Run <var>processCustomFetchResponse</var> with <var>response</var> and
       <var>bodyBytes</var>.</ol>
     </ol>

    <p>In both cases, let <var>onComplete</var> given <var>script</var> be the following steps:</p>

    <ol><li><p>If <var>script</var> is null or if <var>script</var>'s <a href=webappapis.html#concept-script-error-to-rethrow id=worker-processing-model:concept-script-error-to-rethrow>error to rethrow</a> is non-null, then:</p>

     <ol><li><p><a id=worker-processing-model:queue-a-global-task href=webappapis.html#queue-a-global-task>Queue a global task</a> on the <a id=worker-processing-model:dom-manipulation-task-source href=webappapis.html#dom-manipulation-task-source>DOM manipulation task source</a> given
      <var>worker</var>'s <a id=worker-processing-model:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global object</a> to <a href=https://dom.spec.whatwg.org/#concept-event-fire id=worker-processing-model:concept-event-fire data-x-internal=concept-event-fire>fire an event</a> named <code id=worker-processing-model:event-error><a href=indices.html#event-error>error</a></code>
      at <var>worker</var>.<li><p>Run the <a href=webappapis.html#environment-discarding-steps id=worker-processing-model:environment-discarding-steps>environment discarding steps</a>
      for <var>inside settings</var>.<li><p>Abort these steps.</ol>

     <li><p>Associate <var>worker</var> with <var>worker global scope</var>.<li><p>Let <var>inside port</var> be a <a id=worker-processing-model:new href=https://webidl.spec.whatwg.org/#new data-x-internal=new>new</a> <code id=worker-processing-model:messageport-2><a href=web-messaging.html#messageport>MessagePort</a></code> object in
     <var>inside settings</var>'s <a href="webappapis.html#environment-settings-object's-realm" id="worker-processing-model:environment-settings-object's-realm">realm</a>.<li>
      <p>If <var>is shared</var> is false, then:</p>

      <ol><li><p>Set <var>inside port</var>'s <a id=worker-processing-model:message-event-target href=web-messaging.html#message-event-target>message event target</a> to <var>worker global
       scope</var>.<li><p>Set <var>worker global scope</var>'s <a href=#inside-port id=worker-processing-model:inside-port>inside port</a> to <var>inside
       port</var>.</ol>
     <li><p><a id=worker-processing-model:entangle href=web-messaging.html#entangle>Entangle</a> <var>outside port</var> and <var>inside port</var>.<li><p>Create a new <code id=worker-processing-model:workerlocation><a href=#workerlocation>WorkerLocation</a></code> object and associate it with <var>worker global
     scope</var>.</p>

     <li id=step-closing-orphan-workers><p><i>Closing orphan workers</i>: Start monitoring
     <var>worker global scope</var> such that no sooner than it stops being <a href=#protected-worker id=worker-processing-model:protected-worker>protected</a>, and no later than it stops being <a href=#permissible-worker id=worker-processing-model:permissible-worker>permissible</a>, <var>worker global scope</var>'s <a href=#dom-workerglobalscope-closing id=worker-processing-model:dom-workerglobalscope-closing>closing</a> flag is set to true.<li id=step-suspending-workers><p><i>Suspending workers</i>: Start monitoring <var>worker
     global scope</var>, such that whenever <var>worker global scope</var>'s <a href=#dom-workerglobalscope-closing id=worker-processing-model:dom-workerglobalscope-closing-2>closing</a> flag is false and it is <a href=#suspendable-worker id=worker-processing-model:suspendable-worker>suspendable</a>, the user agent suspends execution of script in
     <var>worker global scope</var> until such time as either the <a href=#dom-workerglobalscope-closing id=worker-processing-model:dom-workerglobalscope-closing-3>closing</a> flag switches to true or <var>worker
     global scope</var> stops being <a href=#suspendable-worker id=worker-processing-model:suspendable-worker-2>suspendable</a>.<li><p>Set <var>inside settings</var>'s <a href=webappapis.html#concept-environment-execution-ready-flag id=worker-processing-model:concept-environment-execution-ready-flag>execution ready flag</a>.<li>
      <p>If <var>script</var> is a <a id=worker-processing-model:classic-script href=webappapis.html#classic-script>classic script</a>, then <a href=webappapis.html#run-a-classic-script id=worker-processing-model:run-a-classic-script>run the classic script</a> <var>script</var>. Otherwise, it is a <a id=worker-processing-model:module-script href=webappapis.html#module-script>module
      script</a>; <a href=webappapis.html#run-a-module-script id=worker-processing-model:run-a-module-script>run the module script</a>
      <var>script</var>.</p>

      <p class=note>In addition to the usual possibilities of returning a value or failing due to
      an exception, this could be <a href=webappapis.html#abort-a-running-script id=worker-processing-model:abort-a-running-script>prematurely aborted</a> by
      the <a href=#terminate-a-worker id=worker-processing-model:terminate-a-worker>terminate a worker</a> algorithm defined below.</p>
     <li><p>Enable <var>outside port</var>'s <a id=worker-processing-model:port-message-queue href=web-messaging.html#port-message-queue>port message queue</a>.<li><p>If <var>is shared</var> is false, enable the <a id=worker-processing-model:port-message-queue-2 href=web-messaging.html#port-message-queue>port message queue</a>
     of the worker's implicit port.<li><p>If <var>is shared</var> is true, then <a id=worker-processing-model:queue-a-global-task-2 href=webappapis.html#queue-a-global-task>queue a global task</a> on the <a id=worker-processing-model:dom-manipulation-task-source-2 href=webappapis.html#dom-manipulation-task-source>DOM
     manipulation task source</a> given <var>worker global scope</var> to <a href=https://dom.spec.whatwg.org/#concept-event-fire id=worker-processing-model:concept-event-fire-2 data-x-internal=concept-event-fire>fire an event</a> named <code id=worker-processing-model:event-workerglobalscope-connect><a href=indices.html#event-workerglobalscope-connect>connect</a></code> at <var>worker global scope</var>, using
     <code id=worker-processing-model:messageevent><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=worker-processing-model:dom-messageevent-data><a href=comms.html#dom-messageevent-data>data</a></code> attribute
     initialized to the empty string, the <code id=worker-processing-model:dom-messageevent-ports><a href=comms.html#dom-messageevent-ports>ports</a></code> attribute
     initialized to a new <a id=worker-processing-model:frozen-array href=https://webidl.spec.whatwg.org/#dfn-frozen-array-type data-x-internal=frozen-array>frozen array</a> containing <var>inside port</var>, and the <code id=worker-processing-model:dom-messageevent-source><a href=comms.html#dom-messageevent-source>source</a></code> attribute initialized to <var>inside
     port</var>.<li><p>Enable the <a href=https://w3c.github.io/ServiceWorker/#dfn-client-message-queue id=worker-processing-model:dfn-client-message-queue data-x-internal=dfn-client-message-queue>client message queue</a> of the
     <code id=worker-processing-model:serviceworkercontainer><a data-x-internal=serviceworkercontainer href=https://w3c.github.io/ServiceWorker/#serviceworkercontainer>ServiceWorkerContainer</a></code> object whose associated <a href=https://w3c.github.io/ServiceWorker/#serviceworkercontainer-service-worker-client id=worker-processing-model:serviceworkercontainer-service-worker-client data-x-internal=serviceworkercontainer-service-worker-client>service worker client</a> is
     <var>worker global scope</var>'s <a id=worker-processing-model:relevant-settings-object href=webappapis.html#relevant-settings-object>relevant settings object</a>.<li>
      <p><i>Event loop</i>: Run the <a id=worker-processing-model:responsible-event-loop href=webappapis.html#responsible-event-loop>responsible
      event loop</a> specified by <var>inside settings</var> until it is destroyed.</p>

      <p class=note>The handling of events or the execution of callbacks by <a href=webappapis.html#concept-task id=worker-processing-model:concept-task>tasks</a> run by the <a id=worker-processing-model:event-loop href=webappapis.html#event-loop>event loop</a> might get <a href=webappapis.html#abort-a-running-script id=worker-processing-model:abort-a-running-script-2>prematurely aborted</a> by the <a href=#terminate-a-worker id=worker-processing-model:terminate-a-worker-2>terminate a
      worker</a> algorithm defined below.</p>

      <p class=note>The worker processing model remains on this step until the event loop is
      destroyed, which happens after the <a href=#dom-workerglobalscope-closing id=worker-processing-model:dom-workerglobalscope-closing-4>closing</a>
      flag is set to true, as described in the <a id=worker-processing-model:event-loop-2 href=webappapis.html#event-loop>event loop</a> processing model.</p>
     <li>
      <p><a href=https://infra.spec.whatwg.org/#map-clear id=worker-processing-model:map-clear data-x-internal=map-clear>Clear</a> the <var>worker global scope</var>'s
      <a id=worker-processing-model:map-of-active-timers href=timers-and-user-prompts.html#map-of-active-timers>map of active timers</a>.</p>
     <li>
      <p>Disentangle all the ports in the list of <a href="#the-worker's-ports" id="worker-processing-model:the-worker's-ports">the worker's ports</a>.</p>
     <li>
       <p><a href=https://infra.spec.whatwg.org/#list-empty id=worker-processing-model:list-empty data-x-internal=list-empty>Empty</a> <var>worker global scope</var>'s <a href=#concept-WorkerGlobalScope-owner-set id=worker-processing-model:concept-WorkerGlobalScope-owner-set-2>owner set</a>.</p>
     </ol>
   </ol>

  <hr>

  <p>When a user agent is to <dfn id=terminate-a-worker data-export="">terminate a worker</dfn>, it must run the following steps
  <a id=worker-processing-model:in-parallel href=infrastructure.html#in-parallel>in parallel</a> with the worker's main loop (the "<a href=#run-a-worker id=worker-processing-model:run-a-worker>run a worker</a>" processing
  model defined above):</p>

  <ol><li><p>Set the worker's <code id=worker-processing-model:workerglobalscope><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's <a href=#dom-workerglobalscope-closing id=worker-processing-model:dom-workerglobalscope-closing-5>closing</a> flag to true.<li><p>If there are any <a href=webappapis.html#concept-task id=worker-processing-model:concept-task-2>tasks</a> queued in the
   <code id=worker-processing-model:workerglobalscope-2><a href=#workerglobalscope>WorkerGlobalScope</a></code> object's <a id=worker-processing-model:relevant-agent href=webappapis.html#relevant-agent>relevant agent</a>'s <a href=webappapis.html#concept-agent-event-loop id=worker-processing-model:concept-agent-event-loop>event loop</a>'s <a href=webappapis.html#task-queue id=worker-processing-model:task-queue>task
   queues</a>, discard them without processing them.<li><p><a href=webappapis.html#abort-a-running-script id=worker-processing-model:abort-a-running-script-3>Abort the script</a> currently running in the
   worker.<li><p>If the worker's <code id=worker-processing-model:workerglobalscope-3><a href=#workerglobalscope>WorkerGlobalScope</a></code> object is actually a
   <code id=worker-processing-model:dedicatedworkerglobalscope-3><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object (i.e. the worker is a dedicated worker), then
   empty the <a id=worker-processing-model:port-message-queue-3 href=web-messaging.html#port-message-queue>port message queue</a> of the port that the worker's implicit port is
   entangled with.</ol>

  <p id=terminate-rampant-workers>User agents may invoke the <a href=#terminate-a-worker id=worker-processing-model:terminate-a-worker-3>terminate a worker</a>
  algorithm when a worker stops being <a href=#active-needed-worker id=worker-processing-model:active-needed-worker>actively needed</a> and
  the worker continues executing even after its <a href=#dom-workerglobalscope-closing id=worker-processing-model:dom-workerglobalscope-closing-6>closing</a> flag was set to true.</p>

  


  <h4 id=runtime-script-errors-2><span class=secno>10.2.5</span> Runtime script errors<a href=#runtime-script-errors-2 class=self-link></a></h4>

  <p>Whenever an uncaught runtime script error occurs in one of the worker's scripts, if the error
  did not occur while handling a previous script error, the user agent will <a href=webappapis.html#report-an-exception id=runtime-script-errors-2:report-an-exception>report</a> it for the worker's <code id=runtime-script-errors-2:workerglobalscope><a href=#workerglobalscope>WorkerGlobalScope</a></code> object.</p>


  <h4 id=creating-workers><span class=secno>10.2.6</span> Creating workers<a href=#creating-workers class=self-link></a></h4>

  <h5 id=the-abstractworker-mixin><span class=secno>10.2.6.1</span> <span id=the-abstractworker-abstract-interface></span>The
  <code id=the-abstractworker-mixin:abstractworker><a href=#abstractworker>AbstractWorker</a></code> mixin<a href=#the-abstractworker-mixin class=self-link></a></h5>
  

  <pre><code class='idl'><c- b>interface</c-> <c- b>mixin</c-> <dfn id='abstractworker' data-dfn-type='interface'><c- g>AbstractWorker</c-></dfn> {
  <c- b>attribute</c-> <a id='the-abstractworker-mixin:eventhandler' href='webappapis.html#eventhandler'><c- n>EventHandler</c-></a> <a href='#handler-abstractworker-onerror' id='the-abstractworker-mixin:handler-abstractworker-onerror'><c- g>onerror</c-></a>;
};</code></pre>

  <p>The following are the <a id=the-abstractworker-mixin:event-handlers href=webappapis.html#event-handlers>event handlers</a> (and their corresponding <a href=webappapis.html#event-handler-event-type id=the-abstractworker-mixin:event-handler-event-type>event handler event types</a>) that must be supported,
  as <a id=the-abstractworker-mixin:event-handler-idl-attributes href=webappapis.html#event-handler-idl-attributes>event handler IDL attributes</a>, by objects implementing the
  <code id=the-abstractworker-mixin:abstractworker-2><a href=#abstractworker>AbstractWorker</a></code> interface:</p>

  <table><thead><tr><th><a href=webappapis.html#event-handlers id=the-abstractworker-mixin:event-handlers-2>Event handler</a> <th><a id=the-abstractworker-mixin:event-handler-event-type-2 href=webappapis.html#event-handler-event-type>Event handler event type</a>
   <tbody><tr><td><dfn data-dfn-for=AbstractWorker id=handler-abstractworker-onerror data-dfn-type=attribute><code>onerror</code></dfn> <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/error_event title="The error event fires whenever an error occurs in the service worker.">ServiceWorker/error_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>44+</span></span><span class="safari yes"><span>Safari</span><span>11.1+</span></span><span class="chrome yes"><span>Chrome</span><span>40+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>17+</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/error_event title="The error event of the SharedWorker interface fires when an error occurs in the worker.">SharedWorker/error_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>33+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android no"><span>Chrome Android</span><span>No</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>4.0–5.0</span></span><span class="opera_android no"><span>Opera Android</span><span>11–14</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Worker/error_event title="The error event of the Worker interface fires when an error occurs in the worker.">Worker/error_event</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><td> <code id=the-abstractworker-mixin:event-error><a href=indices.html#event-error>error</a></code>
  </table>


  
  <h5 id=script-settings-for-workers><span class=secno>10.2.6.2</span> Script settings for workers<a href=#script-settings-for-workers class=self-link></a></h5>

  <p>To <dfn id=set-up-a-worker-environment-settings-object>set up a worker environment settings object</dfn>, given a <a id=script-settings-for-workers:javascript-execution-context href=https://tc39.es/ecma262/#sec-execution-contexts data-x-internal=javascript-execution-context>JavaScript execution
  context</a> <var>execution context</var>, an <a id=script-settings-for-workers:environment-settings-object href=webappapis.html#environment-settings-object>environment settings object</a>
  <var>outside settings</var>, and a number <var>unsafeWorkerCreationTime</var>:</p>

  <ol><li><p>Let <var>inherited origin</var> be <var>outside settings</var>'s <a href=webappapis.html#concept-settings-object-origin id=script-settings-for-workers:concept-settings-object-origin>origin</a>.<li><p>Let <var>realm</var> be the value of <var>execution context</var>'s Realm
   component.<li><p>Let <var>worker global scope</var> be <var>realm</var>'s <a href=webappapis.html#concept-realm-global id=script-settings-for-workers:concept-realm-global>global object</a>.<li>
    <p>Let <var>settings object</var> be a new <a id=script-settings-for-workers:environment-settings-object-2 href=webappapis.html#environment-settings-object>environment settings object</a> whose algorithms
    are defined as follows:</p>

    <dl><dt>The <a id=script-settings-for-workers:realm-execution-context href=webappapis.html#realm-execution-context>realm execution context</a><dd>
      <p>Return <var>execution context</var>.
     <dt>The <a href=webappapis.html#concept-settings-object-module-map id=script-settings-for-workers:concept-settings-object-module-map>module map</a><dd>
      <p>Return <var>worker global scope</var>'s <a href=#concept-workerglobalscope-module-map id=script-settings-for-workers:concept-workerglobalscope-module-map>module map</a>.</p>
     <dt>The <a id=script-settings-for-workers:api-base-url href=webappapis.html#api-base-url>API base URL</a><dd>
      <p>Return <var>worker global scope</var>'s <a href=#concept-workerglobalscope-url id=script-settings-for-workers:concept-workerglobalscope-url>url</a>.</p>
     <dt>The <a href=webappapis.html#concept-settings-object-origin id=script-settings-for-workers:concept-settings-object-origin-2>origin</a><dd>
      <p>Return a unique <a href=browsers.html#concept-origin-opaque id=script-settings-for-workers:concept-origin-opaque>opaque origin</a> if <var>worker
      global scope</var>'s <a href=#concept-workerglobalscope-url id=script-settings-for-workers:concept-workerglobalscope-url-2>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-scheme id=script-settings-for-workers:concept-url-scheme data-x-internal=concept-url-scheme>scheme</a> is "<code>data</code>", and <var>inherited
      origin</var> otherwise.</p>
     <dt>The <a href=webappapis.html#concept-settings-object-has-cross-site-ancestor id=script-settings-for-workers:concept-settings-object-has-cross-site-ancestor>has cross-site
     ancestry</a><dd>
      <ol><li><p>If <var>outside settings</var>'s <a href=webappapis.html#concept-settings-object-has-cross-site-ancestor id=script-settings-for-workers:concept-settings-object-has-cross-site-ancestor-2>has cross-site ancestor</a> is
       true, then return true.<li><p>If <var>worker global scope</var>'s <a href=#concept-workerglobalscope-url id=script-settings-for-workers:concept-workerglobalscope-url-3>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-scheme id=script-settings-for-workers:concept-url-scheme-2 data-x-internal=concept-url-scheme>scheme</a> is "<code>data</code>", then return
       true.<li><p>Return false.</ol>
     <dt>The <a href=webappapis.html#concept-settings-object-policy-container id=script-settings-for-workers:concept-settings-object-policy-container>policy container</a><dd>
      <p>Return <var>worker global scope</var>'s <a href=#concept-workerglobalscope-policy-container id=script-settings-for-workers:concept-workerglobalscope-policy-container>policy container</a>.</p>
     <dt>The <a href=webappapis.html#concept-settings-object-cross-origin-isolated-capability id=script-settings-for-workers:concept-settings-object-cross-origin-isolated-capability>cross-origin
     isolated capability</a><dd><p>Return <var>worker global scope</var>'s <a href=#concept-workerglobalscope-cross-origin-isolated-capability id=script-settings-for-workers:concept-workerglobalscope-cross-origin-isolated-capability>cross-origin isolated
     capability</a>.<dt>The <a href=webappapis.html#concept-settings-object-time-origin id=script-settings-for-workers:concept-settings-object-time-origin>time origin</a><dd><p>Return the result of <a href=https://w3c.github.io/hr-time/#dfn-coarsen-time id=script-settings-for-workers:coarsen-time data-x-internal=coarsen-time>coarsening</a>
     <var>unsafeWorkerCreationTime</var> with <var>worker global scope</var>'s <a href=#concept-workerglobalscope-cross-origin-isolated-capability id=script-settings-for-workers:concept-workerglobalscope-cross-origin-isolated-capability-2>cross-origin isolated
     capability</a>.</dl>
   <li><p>Set <var>settings object</var>'s <a href=webappapis.html#concept-environment-id id=script-settings-for-workers:concept-environment-id>id</a> to a new
   unique opaque string, <a href=webappapis.html#concept-environment-creation-url id=script-settings-for-workers:concept-environment-creation-url>creation URL</a> to
   <var>worker global scope</var>'s <a id=script-settings-for-workers:url href=https://url.spec.whatwg.org/#concept-url data-x-internal=url>url</a>, <a id=script-settings-for-workers:concept-environment-top-level-creation-url href=webappapis.html#concept-environment-top-level-creation-url>top-level creation URL</a> to null,
   <a href=webappapis.html#concept-environment-target-browsing-context id=script-settings-for-workers:concept-environment-target-browsing-context>target browsing context</a> to
   null, and <a href=webappapis.html#concept-environment-active-service-worker id=script-settings-for-workers:concept-environment-active-service-worker>active service worker</a>
   to null.<li><p>If <var>worker global scope</var> is a <code id=script-settings-for-workers:dedicatedworkerglobalscope><a href=#dedicatedworkerglobalscope>DedicatedWorkerGlobalScope</a></code> object,
   then set <var>settings object</var>'s <a id=script-settings-for-workers:concept-environment-top-level-origin href=webappapis.html#concept-environment-top-level-origin>top-level origin</a> to <var>outside
   settings</var>'s <a id=script-settings-for-workers:concept-environment-top-level-origin-2 href=webappapis.html#concept-environment-top-level-origin>top-level origin</a>.<li>
    <p>Otherwise, set <var>settings object</var>'s <a id=script-settings-for-workers:concept-environment-top-level-origin-3 href=webappapis.html#concept-environment-top-level-origin>top-level origin</a> to an
    <a id=script-settings-for-workers:implementation-defined href=https://infra.spec.whatwg.org/#implementation-defined data-x-internal=implementation-defined>implementation-defined</a> value.</p>

    <p class=XXX>See <a href=https://privacycg.github.io/storage-partitioning/>Client-Side
    Storage Partitioning</a> for the latest on properly defining this.</p>
   <li><p>Set <var>realm</var>'s [[HostDefined]] field to <var>settings object</var>.<li><p>Return <var>settings object</var>.</ol>
  


  <h5 id=dedicated-workers-and-the-worker-interface><span class=secno>10.2.6.3</span> Dedicated workers and the <code id=worker-dev><a href=#worker>Worker</a></code> interface<a href=#dedicated-workers-and-the-worker-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Worker title="The Worker interface of the Web Workers API represents a background task that can be created via script, which can send messages back to its creator.">Worker</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div>

  <pre><code class='idl'>[<c- g>Exposed</c->=(<c- n>Window</c->,<c- n>DedicatedWorker</c->,<c- n>SharedWorker</c->)]
<c- b>interface</c-> <dfn id='worker' data-dfn-type='interface'><c- g>Worker</c-></dfn> : <a id='dedicated-workers-and-the-worker-interface:eventtarget' href='https://dom.spec.whatwg.org/#interface-eventtarget' data-x-internal='eventtarget'><c- n>EventTarget</c-></a> {
  <a href='#dom-worker' id='dedicated-workers-and-the-worker-interface:dom-worker'><c- g>constructor</c-></a>((<code id='dedicated-workers-and-the-worker-interface:tt-trustedscripturl'><a data-x-internal='tt-trustedscripturl' href='https://w3c.github.io/trusted-types/dist/spec/#trustedscripturl'><c- n>TrustedScriptURL</c-></a></code> <c- b>or</c-> <c- b>USVString</c->) <c- g>scriptURL</c->, <c- b>optional</c-> <a href='#workeroptions' id='dedicated-workers-and-the-worker-interface:workeroptions'><c- n>WorkerOptions</c-></a> <c- g>options</c-> = {});

  <c- b>undefined</c-> <a href='#dom-worker-terminate' id='dedicated-workers-and-the-worker-interface:dom-worker-terminate'><c- g>terminate</c-></a>();

  <c- b>undefined</c-> <a href='#dom-worker-postmessage' id='dedicated-workers-and-the-worker-interface:dom-worker-postmessage'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->, <c- b>sequence</c->&lt;<a href='https://webidl.spec.whatwg.org/#idl-object' id='dedicated-workers-and-the-worker-interface:idl-object' data-x-internal='idl-object'><c- b>object</c-></a>&gt; <c- g>transfer</c->);
  <c- b>undefined</c-> <a href='#dom-worker-postmessage-options' id='dedicated-workers-and-the-worker-interface:dom-worker-postmessage-options'><c- g>postMessage</c-></a>(<c- b>any</c-> <c- g>message</c->, <c- b>optional</c-> <a id='dedicated-workers-and-the-worker-interface:structuredserializeoptions' href='web-messaging.html#structuredserializeoptions'><c- n>StructuredSerializeOptions</c-></a> <c- g>options</c-> = {});
};

<c- b>dictionary</c-> <dfn id='workeroptions' data-dfn-type='dictionary'><c- g>WorkerOptions</c-></dfn> {
  <c- b>DOMString</c-> <dfn data-dfn-for='WorkerOptions' id='dom-workeroptions-name' data-dfn-type='dict-member'><c- g>name</c-></dfn> = &quot;&quot;;
  <a href='#workertype' id='dedicated-workers-and-the-worker-interface:workertype'><c- n>WorkerType</c-></a> <dfn data-dfn-for='WorkerOptions' id='dom-workeroptions-type' data-dfn-type='dict-member'><c- g>type</c-></dfn> = &quot;classic&quot;;
  <a id='dedicated-workers-and-the-worker-interface:requestcredentials' href='https://fetch.spec.whatwg.org/#requestcredentials' data-x-internal='requestcredentials'><c- n>RequestCredentials</c-></a> <dfn data-dfn-for='WorkerOptions' id='dom-workeroptions-credentials' data-dfn-type='dict-member'><c- g>credentials</c-></dfn> = &quot;same-origin&quot;; // credentials is only used if type is &quot;module&quot;
};

<c- b>enum</c-> <dfn id='workertype' data-dfn-type='enum'><c- g>WorkerType</c-></dfn> { <c- s>&quot;classic&quot;</c->, <c- s>&quot;module&quot;</c-> };

<a href='#worker' id='dedicated-workers-and-the-worker-interface:worker'><c- n>Worker</c-></a> <c- b>includes</c-> <a href='#abstractworker' id='dedicated-workers-and-the-worker-interface:abstractworker'><c- n>AbstractWorker</c-></a>;
<a href='#worker' id='dedicated-workers-and-the-worker-interface:worker-2'><c- n>Worker</c-></a> <c- b>includes</c-> <a id='dedicated-workers-and-the-worker-interface:messageeventtarget' href='web-messaging.html#messageeventtarget'><c- n>MessageEventTarget</c-></a>;</code></pre>

  <dl class=domintro><dt><code><var>worker</var> = new <a href=#dom-worker id=dom-worker-dev>Worker</a>(<var>scriptURL</var> [, <var>options</var> ])</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker title="The Worker() constructor creates a Worker object that executes the script at the specified URL. This script must obey the same-origin policy.">Worker/Worker</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd>
    <p>Returns a new <code id=dedicated-workers-and-the-worker-interface:worker-3><a href=#worker>Worker</a></code> object. <var>scriptURL</var> will be fetched and executed
    in the background, creating a new global environment for which <var>worker</var> represents the
    communication channel.</p>

    <p><var>options</var> can contain the following values:</p>

    <ul><li><p><code id=dom-workeroptions-name-dev><a href=#dom-workeroptions-name>name</a></code> can be used to define the <a href=#concept-workerglobalscope-name id=dedicated-workers-and-the-worker-interface:concept-workerglobalscope-name>name</a> of that global environment, primarily for
     debugging purposes.<li><p><code id=dom-workeroptions-type-dev><a href=#dom-workeroptions-type>type</a></code> can be used to load the new
     global environment from <var>scriptURL</var> as a JavaScript module, by setting it to the value
     "<code>module</code>".<li><p><code id=dom-workeroptions-credentials-dev><a href=#dom-workeroptions-credentials>credentials</a></code> can be used to
     specify how <var>scriptURL</var> is fetched, but only if <code id=dedicated-workers-and-the-worker-interface:dom-workeroptions-type><a href=#dom-workeroptions-type>type</a></code> is set to "<code>module</code>".</ul>
   <dt><code><var>worker</var>.<a href=#dom-worker-terminate id=dom-worker-terminate-dev>terminate</a>()</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Worker/terminate title="The terminate() method of the Worker interface immediately terminates the Worker. This does not offer the worker an opportunity to finish its operations; it is stopped at once.">Worker/terminate</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dd>Aborts <var>worker</var>'s associated global environment.<dt><code><var>worker</var>.<a href=#dom-worker-postmessage id=dom-worker-postmessage-dev>postMessage</a>(<var>message</var> [, <var>transfer</var> ])</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage title="The postMessage() method of the Worker interface sends a message to the worker. The first parameter is the data to send to the worker. The data may be any JavaScript object that can be handled by the structured clone algorithm.">Worker/postMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>2+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>11+</span></span></div></div></div><dt><code><var>worker</var>.<a href=#dom-worker-postmessage-options id=dom-worker-postmessage-options-dev>postMessage</a>(<var>message</var> [, { <a href=web-messaging.html#dom-structuredserializeoptions-transfer id=dedicated-workers-and-the-worker-interface:dom-structuredserializeoptions-transfer>transfer</a> } ])</code><dd><p>Clones <var>message</var> and transmits it to <var>worker</var>'s global environment.
   <var>transfer</var> can be passed as a list of objects that are to be transferred rather than
   cloned.</dl>

  

  <p>Each <code id=dedicated-workers-and-the-worker-interface:worker-4><a href=#worker>Worker</a></code> object has an associated <dfn data-dfn-for=Worker id=outside-port>outside port</dfn> (a
  <code id=dedicated-workers-and-the-worker-interface:messageport><a href=web-messaging.html#messageport>MessagePort</a></code>). This port is part of a channel that is set up when the worker is
  created, but it is not exposed. This object must never be garbage collected before the
  <code id=dedicated-workers-and-the-worker-interface:worker-5><a href=#worker>Worker</a></code> object.</p>

  <p>The <dfn data-dfn-for=Worker id=dom-worker-terminate data-dfn-type=method><code>terminate()</code></dfn>
  method steps are to <a href=#terminate-a-worker id=dedicated-workers-and-the-worker-interface:terminate-a-worker>terminate a worker</a> given <a id=dedicated-workers-and-the-worker-interface:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s worker.</p>

  

  <p>The <dfn data-dfn-for=Worker id=dom-worker-postmessage data-dfn-type=method><code>postMessage(<var>message</var>, <var>transfer</var>)</code></dfn>
  and <dfn data-dfn-for=Worker id=dom-worker-postmessage-options data-dfn-type=method><code>postMessage(<var>message</var>,
  <var>options</var>)</code></dfn> methods on <code id=dedicated-workers-and-the-worker-interface:worker-6><a href=#worker>Worker</a></code> objects act as if, when invoked,
  they immediately invoked the respective <code id=dedicated-workers-and-the-worker-interface:dom-messageport-postmessage><a href=web-messaging.html#dom-messageport-postmessage>postMessage(<var>message</var>, <var>transfer</var>)</a></code>
  and <code id=dedicated-workers-and-the-worker-interface:dom-messageport-postmessage-options><a href=web-messaging.html#dom-messageport-postmessage-options>postMessage(<var>message</var>,
  <var>options</var>)</a></code> on <a id=dedicated-workers-and-the-worker-interface:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#outside-port id=dedicated-workers-and-the-worker-interface:outside-port>outside port</a>, with the same
  arguments, and returned the same return value.</p>

  

  <div class=example>

   <p>The <code id=dedicated-workers-and-the-worker-interface:dom-worker-postmessage-2><a href=#dom-worker-postmessage>postMessage()</a></code>
   method's first argument can be structured data:</p>

   <pre><code class='js'>worker<c- p>.</c->postMessage<c- p>({</c->opcode<c- o>:</c-> <c- t>&apos;activate&apos;</c-><c- p>,</c-> device<c- o>:</c-> <c- mf>1938</c-><c- p>,</c-> parameters<c- o>:</c-> <c- p>[</c-><c- mf>23</c-><c- p>,</c-> <c- mf>102</c-><c- p>]});</c-></code></pre>

  </div>

  

  <hr>

  <p>The <dfn data-dfn-for=Worker id=dom-worker data-dfn-type=constructor><code>new Worker(<var>scriptURL</var>,
  <var>options</var>)</code></dfn> constructor steps are:</p>

  <ol><li><p>Let <var>compliantScriptURL</var> be the result of invoking the <a href=https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm id=dedicated-workers-and-the-worker-interface:tt-getcompliantstring data-x-internal=tt-getcompliantstring>Get Trusted Type compliant string</a> algorithm with <code id=dedicated-workers-and-the-worker-interface:tt-trustedscripturl-2><a data-x-internal=tt-trustedscripturl href=https://w3c.github.io/trusted-types/dist/spec/#trustedscripturl>TrustedScriptURL</a></code>, <a id=dedicated-workers-and-the-worker-interface:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=dedicated-workers-and-the-worker-interface:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global
   object</a>, <var>scriptURL</var>, "<code>Worker constructor</code>", and "<code>script</code>".<li><p>Let <var>outsideSettings</var> be <a id=dedicated-workers-and-the-worker-interface:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=dedicated-workers-and-the-worker-interface:relevant-settings-object href=webappapis.html#relevant-settings-object>relevant settings
   object</a>.</p>

   <li>
    <p>Let <var>workerURL</var> be the result of <a id=dedicated-workers-and-the-worker-interface:encoding-parsing-a-url href=urls-and-fetching.html#encoding-parsing-a-url>encoding-parsing a URL</a> given
    <var>compliantScriptURL</var>, relative to <var>outsideSettings</var>.</p>

    <p class=note>Any <a href=browsers.html#same-origin id=dedicated-workers-and-the-worker-interface:same-origin>same-origin</a> URL (including <code id=dedicated-workers-and-the-worker-interface:blob-protocol><a data-x-internal=blob-protocol href=https://w3c.github.io/FileAPI/#DefinitionOfScheme>blob:</a></code> URLs) can be used. <code id=dedicated-workers-and-the-worker-interface:data-protocol><a data-x-internal=data-protocol href=https://www.rfc-editor.org/rfc/rfc2397#section-2>data:</a></code>
    URLs can also be used, but they create a worker with an <a href=browsers.html#concept-origin-opaque id=dedicated-workers-and-the-worker-interface:concept-origin-opaque>opaque origin</a>.</p>
   <li><p>If <var>workerURL</var> is failure, then throw a <a id=dedicated-workers-and-the-worker-interface:syntaxerror href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a>
   <code id=dedicated-workers-and-the-worker-interface:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>outsidePort</var> be a <a id=dedicated-workers-and-the-worker-interface:new href=https://webidl.spec.whatwg.org/#new data-x-internal=new>new</a> <code id=dedicated-workers-and-the-worker-interface:messageport-2><a href=web-messaging.html#messageport>MessagePort</a></code> in
   <var>outsideSettings</var>'s <a href="webappapis.html#environment-settings-object's-realm" id="dedicated-workers-and-the-worker-interface:environment-settings-object's-realm">realm</a>.<li><p>Set <var>outsidePort</var>'s <a id=dedicated-workers-and-the-worker-interface:message-event-target href=web-messaging.html#message-event-target>message event target</a> to
   <a id=dedicated-workers-and-the-worker-interface:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li><p>Set <a id=dedicated-workers-and-the-worker-interface:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#outside-port id=dedicated-workers-and-the-worker-interface:outside-port-2>outside port</a> to <var>outsidePort</var>.<li><p>Let <var>worker</var> be <a id=dedicated-workers-and-the-worker-interface:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li>
    <p>Run this step <a id=dedicated-workers-and-the-worker-interface:in-parallel href=infrastructure.html#in-parallel>in parallel</a>:</p>

    <ol><li><p><a href=#run-a-worker id=dedicated-workers-and-the-worker-interface:run-a-worker>Run a worker</a> given <var>worker</var>, <var>workerURL</var>,
     <var>outsideSettings</var>, <var>outsidePort</var>, and <var>options</var>.</ol>
   </ol>

  


  <h5 id=shared-workers-and-the-sharedworker-interface><span class=secno>10.2.6.4</span> Shared workers and the <code id=sharedworker-dev><a href=#sharedworker>SharedWorker</a></code> interface<a href=#shared-workers-and-the-sharedworker-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker title="The SharedWorker interface represents a specific kind of worker that can be accessed from several browsing contexts, such as several windows, iframes or even workers. They implement an interface different than dedicated workers and have a different global scope, SharedWorkerGlobalScope.">SharedWorker</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>33+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android no"><span>Chrome Android</span><span>No</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>4.0–5.0</span></span><span class="opera_android no"><span>Opera Android</span><span>11–14</span></span></div></div></div>

  <pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Window</c->]
<c- b>interface</c-> <dfn id='sharedworker' data-dfn-type='interface'><c- g>SharedWorker</c-></dfn> : <a id='shared-workers-and-the-sharedworker-interface:eventtarget' href='https://dom.spec.whatwg.org/#interface-eventtarget' data-x-internal='eventtarget'><c- n>EventTarget</c-></a> {
  <a href='#dom-sharedworker' id='shared-workers-and-the-sharedworker-interface:dom-sharedworker'><c- g>constructor</c-></a>((<code id='shared-workers-and-the-sharedworker-interface:tt-trustedscripturl'><a data-x-internal='tt-trustedscripturl' href='https://w3c.github.io/trusted-types/dist/spec/#trustedscripturl'><c- n>TrustedScriptURL</c-></a></code> <c- b>or</c-> <c- b>USVString</c->) <c- g>scriptURL</c->, <c- b>optional</c-> (<c- b>DOMString</c-> <c- b>or</c-> <a href='#workeroptions' id='shared-workers-and-the-sharedworker-interface:workeroptions'><c- n>WorkerOptions</c-></a>) <c- g>options</c-> = {});

  <c- b>readonly</c-> <c- b>attribute</c-> <a id='shared-workers-and-the-sharedworker-interface:messageport' href='web-messaging.html#messageport'><c- n>MessagePort</c-></a> <a href='#dom-sharedworker-port' id='shared-workers-and-the-sharedworker-interface:dom-sharedworker-port'><c- g>port</c-></a>;
};
<a href='#sharedworker' id='shared-workers-and-the-sharedworker-interface:sharedworker'><c- n>SharedWorker</c-></a> <c- b>includes</c-> <a href='#abstractworker' id='shared-workers-and-the-sharedworker-interface:abstractworker'><c- n>AbstractWorker</c-></a>;</code></pre>

  <dl class=domintro><dt><code><var>sharedWorker</var> = new <a href=#dom-sharedworker id=dom-sharedworker-dev>SharedWorker</a>(<var>scriptURL</var> [, <var>name</var> ])</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker title="The SharedWorker() constructor creates a SharedWorker object that executes the script at the specified URL. This script must obey the same-origin policy.">SharedWorker/SharedWorker</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>33+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android no"><span>Chrome Android</span><span>No</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>4.0–5.0</span></span><span class="opera_android no"><span>Opera Android</span><span>11–14</span></span></div></div></div><dd><p>Returns a new <code id=shared-workers-and-the-sharedworker-interface:sharedworker-2><a href=#sharedworker>SharedWorker</a></code> object. <var>scriptURL</var> will be fetched and
   executed in the background, creating a new global environment for which <var>sharedWorker</var>
   represents the communication channel. <var>name</var> can be used to define the <a href=#concept-workerglobalscope-name id=shared-workers-and-the-sharedworker-interface:concept-workerglobalscope-name>name</a> of that global environment.<dt><code><var>sharedWorker</var> = new <a href=#dom-sharedworker id=shared-workers-and-the-sharedworker-interface:dom-sharedworker-2>SharedWorker</a>(<var>scriptURL</var> [, <var>options</var> ])</code><dd>
    <p>Returns a new <code id=shared-workers-and-the-sharedworker-interface:sharedworker-3><a href=#sharedworker>SharedWorker</a></code> object. <var>scriptURL</var> will be fetched and
    executed in the background, creating a new global environment for which <var>sharedWorker</var>
    represents the communication channel.</p>

    <p><var>options</var> can contain the following values:</p>

    <ul><li><p><code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-name><a href=#dom-workeroptions-name>name</a></code> can be used to define the <a href=#concept-workerglobalscope-name id=shared-workers-and-the-sharedworker-interface:concept-workerglobalscope-name-2>name</a> of that global environment.<li><p><code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-type><a href=#dom-workeroptions-type>type</a></code> can be used to load the new global
     environment from <var>scriptURL</var> as a JavaScript module, by setting it to the value "<code>module</code>".<li><p><code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-credentials><a href=#dom-workeroptions-credentials>credentials</a></code> can be used to specify
     how <var>scriptURL</var> is fetched, but only if <code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-type-2><a href=#dom-workeroptions-type>type</a></code> is set to "<code>module</code>".</ul>

    <p>Note that attempting to construct a shared worker with <var>options</var> whose <code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-type-3><a href=#dom-workeroptions-type>type</a></code>, or <code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-credentials-2><a href=#dom-workeroptions-credentials>credentials</a></code> values mismatch those
    of an existing shared worker with the same <a href=#concept-sharedworkerglobalscope-constructor-url id=shared-workers-and-the-sharedworker-interface:concept-sharedworkerglobalscope-constructor-url>constructor URL</a> and <a href=#concept-workerglobalscope-name id=shared-workers-and-the-sharedworker-interface:concept-workerglobalscope-name-3>name</a>, will cause the returned
    <var>sharedWorker</var> to fire an <code id=shared-workers-and-the-sharedworker-interface:event-error><a href=indices.html#event-error>error</a></code> event and not connect
    to the existing shared worker.</p>
   <dt><code><var>sharedWorker</var>.<a href=#dom-sharedworker-port id=dom-sharedworker-port-dev>port</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/port title="The port property of the SharedWorker interface returns a MessagePort object used to communicate and control the shared worker.">SharedWorker/port</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>16+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span><hr><span class="opera yes"><span>Opera</span><span>10.6+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android yes"><span>Firefox Android</span><span>33+</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>16+</span></span><span class="chrome_android no"><span>Chrome Android</span><span>No</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>4.0–5.0</span></span><span class="opera_android no"><span>Opera Android</span><span>11–14</span></span></div></div></div><dd><p>Returns <var>sharedWorker</var>'s <code id=shared-workers-and-the-sharedworker-interface:messageport-2><a href=web-messaging.html#messageport>MessagePort</a></code> object which can be used to
   communicate with the global environment.</dl>

  

  <p>A user agent has an associated <dfn id=shared-worker-manager>shared worker manager</dfn> which is the result of
  <a id=shared-workers-and-the-sharedworker-interface:starting-a-new-parallel-queue href=infrastructure.html#starting-a-new-parallel-queue>starting a new parallel queue</a>.</p>

  <p class=note>Each user agent has a single <a href=#shared-worker-manager id=shared-workers-and-the-sharedworker-interface:shared-worker-manager>shared worker manager</a> for simplicity.
  Implementations could use one per <a id=shared-workers-and-the-sharedworker-interface:concept-origin href=browsers.html#concept-origin>origin</a>; that would not be observably different and
  enables more concurrency.</p>

  <hr>

  <p>Each <code id=shared-workers-and-the-sharedworker-interface:sharedworker-4><a href=#sharedworker>SharedWorker</a></code> has a <dfn id=concept-sharedworker-port>port</dfn>, a
  <code id=shared-workers-and-the-sharedworker-interface:messageport-3><a href=web-messaging.html#messageport>MessagePort</a></code> set when the object is created.</p>

  <p>The <dfn data-dfn-for=SharedWorker id=dom-sharedworker-port data-dfn-type=attribute><code>port</code></dfn>
  getter steps are to return <a id=shared-workers-and-the-sharedworker-interface:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-sharedworker-port id=shared-workers-and-the-sharedworker-interface:concept-sharedworker-port>port</a>.</p>

  <p>The <dfn data-dfn-for=SharedWorker id=dom-sharedworker data-dfn-type=constructor><code>new
  SharedWorker(<var>scriptURL</var>, <var>options</var>)</code></dfn> constructor steps are:</p>

  <ol><li><p>Let <var>compliantScriptURL</var> be the result of invoking the <a href=https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm id=shared-workers-and-the-sharedworker-interface:tt-getcompliantstring data-x-internal=tt-getcompliantstring>Get Trusted Type compliant string</a> algorithm with <code id=shared-workers-and-the-sharedworker-interface:tt-trustedscripturl-2><a data-x-internal=tt-trustedscripturl href=https://w3c.github.io/trusted-types/dist/spec/#trustedscripturl>TrustedScriptURL</a></code>, <a id=shared-workers-and-the-sharedworker-interface:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=shared-workers-and-the-sharedworker-interface:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global
   object</a>, <var>scriptURL</var>, "<code>SharedWorker constructor</code>", and
   "<code>script</code>".<li><p>If <var>options</var> is a <code id=shared-workers-and-the-sharedworker-interface:idl-domstring><a data-x-internal=idl-domstring href=https://webidl.spec.whatwg.org/#idl-DOMString>DOMString</a></code>, set
   <var>options</var> to a new <code id=shared-workers-and-the-sharedworker-interface:workeroptions-2><a href=#workeroptions>WorkerOptions</a></code> dictionary whose <code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-name-2><a href=#dom-workeroptions-name>name</a></code> member is set to the value of <var>options</var> and
   whose other members are set to their default values.<li><p>Let <var>outsideSettings</var> be <a id=shared-workers-and-the-sharedworker-interface:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=shared-workers-and-the-sharedworker-interface:relevant-settings-object href=webappapis.html#relevant-settings-object>relevant settings
   object</a>.<li>
    <p>Let <var>urlRecord</var> be the result of <a id=shared-workers-and-the-sharedworker-interface:encoding-parsing-a-url href=urls-and-fetching.html#encoding-parsing-a-url>encoding-parsing a URL</a> given
    <var>compliantScriptURL</var>, relative to <var>outsideSettings</var>.</p>

    <p class=note>Any <a href=browsers.html#same-origin id=shared-workers-and-the-sharedworker-interface:same-origin>same-origin</a> URL (including <code id=shared-workers-and-the-sharedworker-interface:blob-protocol><a data-x-internal=blob-protocol href=https://w3c.github.io/FileAPI/#DefinitionOfScheme>blob:</a></code> URLs) can be used. <code id=shared-workers-and-the-sharedworker-interface:data-protocol><a data-x-internal=data-protocol href=https://www.rfc-editor.org/rfc/rfc2397#section-2>data:</a></code>
    URLs can also be used, but they create a worker with an <a href=browsers.html#concept-origin-opaque id=shared-workers-and-the-sharedworker-interface:concept-origin-opaque>opaque origin</a>.</p>
   <li><p>If <var>urlRecord</var> is failure, then throw a <a id=shared-workers-and-the-sharedworker-interface:syntaxerror href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a>
   <code id=shared-workers-and-the-sharedworker-interface:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>outsidePort</var> be a <a id=shared-workers-and-the-sharedworker-interface:new href=https://webidl.spec.whatwg.org/#new data-x-internal=new>new</a> <code id=shared-workers-and-the-sharedworker-interface:messageport-4><a href=web-messaging.html#messageport>MessagePort</a></code> in
   <var>outsideSettings</var>'s <a href="webappapis.html#environment-settings-object's-realm" id="shared-workers-and-the-sharedworker-interface:environment-settings-object's-realm">realm</a>.<li><p>Set <a id=shared-workers-and-the-sharedworker-interface:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-sharedworker-port id=shared-workers-and-the-sharedworker-interface:concept-sharedworker-port-2>port</a> to
   <var>outsidePort</var>.<li><p>Let <var>callerIsSecureContext</var> be true if <var>outsideSettings</var> is a
   <a id=shared-workers-and-the-sharedworker-interface:secure-context href=webappapis.html#secure-context>secure context</a>; otherwise, false.<li><p>Let <var>outsideStorageKey</var> be the result of running <a id=shared-workers-and-the-sharedworker-interface:obtain-a-storage-key-for-non-storage-purposes href=https://storage.spec.whatwg.org/#obtain-a-storage-key-for-non-storage-purposes data-x-internal=obtain-a-storage-key-for-non-storage-purposes>obtain a storage key for
   non-storage purposes</a> given <var>outsideSettings</var>.<li><p>Let <var>worker</var> be <a id=shared-workers-and-the-sharedworker-interface:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li>
    <p><a id=shared-workers-and-the-sharedworker-interface:enqueue-the-following-steps href=infrastructure.html#enqueue-the-following-steps>Enqueue the following steps</a> to the <a href=#shared-worker-manager id=shared-workers-and-the-sharedworker-interface:shared-worker-manager-2>shared worker manager</a>:</p>

    <ol><li><p>Let <var>workerGlobalScope</var> be null.<li>
      <p><a href=https://infra.spec.whatwg.org/#list-iterate id=shared-workers-and-the-sharedworker-interface:list-iterate data-x-internal=list-iterate>For each</a> <var>scope</var> in the list of all
      <code id=shared-workers-and-the-sharedworker-interface:sharedworkerglobalscope><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> objects:</p>

      <ol><li><p>Let <var>workerStorageKey</var> be the result of running <a id=shared-workers-and-the-sharedworker-interface:obtain-a-storage-key-for-non-storage-purposes-2 href=https://storage.spec.whatwg.org/#obtain-a-storage-key-for-non-storage-purposes data-x-internal=obtain-a-storage-key-for-non-storage-purposes>obtain a storage key
        for non-storage purposes</a> given <var>scope</var>'s <a id=shared-workers-and-the-sharedworker-interface:relevant-settings-object-2 href=webappapis.html#relevant-settings-object>relevant settings
        object</a>.<li>
         <p>If all of the following are true:</p>

         <ul><li><var>workerStorageKey</var> <a href=https://storage.spec.whatwg.org/#storage-key-equal id=shared-workers-and-the-sharedworker-interface:storage-key-equal data-x-internal=storage-key-equal>equals</a>
          <var>outsideStorageKey</var>;<li><var>scope</var>'s <a href=#dom-workerglobalscope-closing id=shared-workers-and-the-sharedworker-interface:dom-workerglobalscope-closing>closing</a> flag is
          false;<li><var>scope</var>'s <a href=#concept-sharedworkerglobalscope-constructor-url id=shared-workers-and-the-sharedworker-interface:concept-sharedworkerglobalscope-constructor-url-2>
          constructor URL</a> <a href=https://url.spec.whatwg.org/#concept-url-equals id=shared-workers-and-the-sharedworker-interface:concept-url-equals data-x-internal=concept-url-equals>equals</a>
          <var>urlRecord</var>; and<li><var>scope</var>'s <a href=#concept-workerglobalscope-name id=shared-workers-and-the-sharedworker-interface:concept-workerglobalscope-name-4>name</a> equals
          <var>options</var>["<code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-name-3><a href=#dom-workeroptions-name>name</a></code>"],</ul>

         <p>then:</p>

         <ol><li><p>Set <var>workerGlobalScope</var> to <var>scope</var>.<li><p><a id=shared-workers-and-the-sharedworker-interface:break href=https://infra.spec.whatwg.org/#iteration-break data-x-internal=break>Break</a>.</ol>
        </ol>

      <p class=note><code id=shared-workers-and-the-sharedworker-interface:data-protocol-2><a data-x-internal=data-protocol href=https://www.rfc-editor.org/rfc/rfc2397#section-2>data:</a></code> URLs create a worker with an <a href=browsers.html#concept-origin-opaque id=shared-workers-and-the-sharedworker-interface:concept-origin-opaque-2>opaque origin</a>. Both the <a href=#concept-sharedworkerglobalscope-constructor-origin id=shared-workers-and-the-sharedworker-interface:concept-sharedworkerglobalscope-constructor-origin>constructor origin</a> and
      <a href=#concept-sharedworkerglobalscope-constructor-url id=shared-workers-and-the-sharedworker-interface:concept-sharedworkerglobalscope-constructor-url-3>constructor URL</a> are
      compared so the same <code id=shared-workers-and-the-sharedworker-interface:data-protocol-3><a data-x-internal=data-protocol href=https://www.rfc-editor.org/rfc/rfc2397#section-2>data:</a></code> URL can be used within an
      <a id=shared-workers-and-the-sharedworker-interface:concept-origin-2 href=browsers.html#concept-origin>origin</a> to get to the same <code id=shared-workers-and-the-sharedworker-interface:sharedworkerglobalscope-2><a href=#sharedworkerglobalscope>SharedWorkerGlobalScope</a></code> object, but cannot
      be used to bypass the <a id=shared-workers-and-the-sharedworker-interface:same-origin-2 href=browsers.html#same-origin>same origin</a> restriction.</p>
     <li>
      <p>If <var>workerGlobalScope</var> is not null, but the user agent has been configured to
      disallow communication between the worker represented by the <var>workerGlobalScope</var> and
      the <a href=webappapis.html#concept-script id=shared-workers-and-the-sharedworker-interface:concept-script>scripts</a> whose <a href=webappapis.html#settings-object id=shared-workers-and-the-sharedworker-interface:settings-object>settings object</a> is <var>outsideSettings</var>,
      then set <var>workerGlobalScope</var> to null.</p>

      <p class=note>For example, a user agent could have a development mode that isolates a
      particular <a id=shared-workers-and-the-sharedworker-interface:top-level-traversable href=document-sequences.html#top-level-traversable>top-level traversable</a> from all other pages, and scripts in that
      development mode could be blocked from connecting to shared workers running in the normal
      browser mode.</p>
     <li>
      <p>If <var>workerGlobalScope</var> is not null, and any of the following are true:</p>

      <ul><li><p><var>workerGlobalScope</var>'s <a href=#concept-workerglobalscope-type id=shared-workers-and-the-sharedworker-interface:concept-workerglobalscope-type>type</a> is not equal to <var>options</var>["<code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-type-4><a href=#dom-workeroptions-type>type</a></code>"]; or<li><p><var>workerGlobalScope</var>'s <a href=#concept-sharedworkerglobalscope-credentials id=shared-workers-and-the-sharedworker-interface:concept-sharedworkerglobalscope-credentials>credentials</a> is not equal to
       <var>options</var>["<code id=shared-workers-and-the-sharedworker-interface:dom-workeroptions-credentials-3><a href=#dom-workeroptions-credentials>credentials</a></code>"]</ul>

      <p>then:</p>

      <ol><li><p><a id=shared-workers-and-the-sharedworker-interface:queue-a-global-task href=webappapis.html#queue-a-global-task>Queue a global task</a> on the <a id=shared-workers-and-the-sharedworker-interface:dom-manipulation-task-source href=webappapis.html#dom-manipulation-task-source>DOM manipulation task source</a>
       given <var>worker</var>'s <a id=shared-workers-and-the-sharedworker-interface:concept-relevant-global-2 href=webappapis.html#concept-relevant-global>relevant global object</a> to <a href=https://dom.spec.whatwg.org/#concept-event-fire id=shared-workers-and-the-sharedworker-interface:concept-event-fire data-x-internal=concept-event-fire>fire an event</a> named <code id=shared-workers-and-the-sharedworker-interface:event-error-2><a href=indices.html#event-error>error</a></code> at <var>worker</var>.<li><p>Abort these steps.</ol>
     <li>
      <p>If <var>workerGlobalScope</var> is not null:</p>

      <ol><li><p>Let <var>insideSettings</var> be <var>workerGlobalScope</var>'s <a id=shared-workers-and-the-sharedworker-interface:relevant-settings-object-3 href=webappapis.html#relevant-settings-object>relevant
       settings object</a>.<li><p>Let <var>workerIsSecureContext</var> be true if <var>insideSettings</var> is a
       <a id=shared-workers-and-the-sharedworker-interface:secure-context-2 href=webappapis.html#secure-context>secure context</a>; otherwise, false.<li>
        <p>If <var>workerIsSecureContext</var> is not <var>callerIsSecureContext</var>:</p>

        <ol><li><p><a id=shared-workers-and-the-sharedworker-interface:queue-a-global-task-2 href=webappapis.html#queue-a-global-task>Queue a global task</a> on the <a id=shared-workers-and-the-sharedworker-interface:dom-manipulation-task-source-2 href=webappapis.html#dom-manipulation-task-source>DOM manipulation task source</a>
         given <var>worker</var>'s <a id=shared-workers-and-the-sharedworker-interface:concept-relevant-global-3 href=webappapis.html#concept-relevant-global>relevant global object</a> to <a href=https://dom.spec.whatwg.org/#concept-event-fire id=shared-workers-and-the-sharedworker-interface:concept-event-fire-2 data-x-internal=concept-event-fire>fire an event</a> named <code id=shared-workers-and-the-sharedworker-interface:event-error-3><a href=indices.html#event-error>error</a></code> at <var>worker</var>.<li><p>Abort these steps.</ol>
       <li><p>Associate <var>worker</var> with <var>workerGlobalScope</var>.<li><p>Let <var>insidePort</var> be a <a id=shared-workers-and-the-sharedworker-interface:new-2 href=https://webidl.spec.whatwg.org/#new data-x-internal=new>new</a> <code id=shared-workers-and-the-sharedworker-interface:messageport-5><a href=web-messaging.html#messageport>MessagePort</a></code> in
       <var>insideSettings</var>'s <a href="webappapis.html#environment-settings-object's-realm" id="shared-workers-and-the-sharedworker-interface:environment-settings-object's-realm-2">realm</a>.<li><p><a id=shared-workers-and-the-sharedworker-interface:entangle href=web-messaging.html#entangle>Entangle</a> <var>outsidePort</var> and <var>insidePort</var>.<li><p><a id=shared-workers-and-the-sharedworker-interface:queue-a-global-task-3 href=webappapis.html#queue-a-global-task>Queue a global task</a> on the <a id=shared-workers-and-the-sharedworker-interface:dom-manipulation-task-source-3 href=webappapis.html#dom-manipulation-task-source>DOM manipulation task source</a>
       given <var>workerGlobalScope</var> to <a href=https://dom.spec.whatwg.org/#concept-event-fire id=shared-workers-and-the-sharedworker-interface:concept-event-fire-3 data-x-internal=concept-event-fire>fire an event</a>
       named <code id=shared-workers-and-the-sharedworker-interface:event-workerglobalscope-connect><a href=indices.html#event-workerglobalscope-connect>connect</a></code> at
       <var>workerGlobalScope</var>, using <code id=shared-workers-and-the-sharedworker-interface:messageevent><a href=comms.html#messageevent>MessageEvent</a></code>, with the <code id=shared-workers-and-the-sharedworker-interface:dom-messageevent-data><a href=comms.html#dom-messageevent-data>data</a></code> attribute initialized to the empty string, the
       <code id=shared-workers-and-the-sharedworker-interface:dom-messageevent-ports><a href=comms.html#dom-messageevent-ports>ports</a></code> attribute initialized to a new
       <a id=shared-workers-and-the-sharedworker-interface:frozen-array href=https://webidl.spec.whatwg.org/#dfn-frozen-array-type data-x-internal=frozen-array>frozen array</a> containing only <var>insidePort</var>, and the <code id=shared-workers-and-the-sharedworker-interface:dom-messageevent-source><a href=comms.html#dom-messageevent-source>source</a></code> attribute initialized to
       <var>insidePort</var>.<li><p><a href=https://infra.spec.whatwg.org/#set-append id=shared-workers-and-the-sharedworker-interface:set-append data-x-internal=set-append>Append</a> the <a href=#relevant-owner-to-add id=shared-workers-and-the-sharedworker-interface:relevant-owner-to-add>relevant owner to add</a> given
       <var>outsideSettings</var> to <var>workerGlobalScope</var>'s <a href=#concept-WorkerGlobalScope-owner-set id=shared-workers-and-the-sharedworker-interface:concept-WorkerGlobalScope-owner-set>owner set</a>.</ol>
     <li><p>Otherwise, <a id=shared-workers-and-the-sharedworker-interface:in-parallel href=infrastructure.html#in-parallel>in parallel</a>, <a href=#run-a-worker id=shared-workers-and-the-sharedworker-interface:run-a-worker>run a worker</a> given <var>worker</var>,
     <var>urlRecord</var>, <var>outsideSettings</var>, <var>outsidePort</var>, and
     <var>options</var>.</ol>
   </ol>

  


  <h4 id=navigator.hardwareconcurrency><span class=secno>10.2.7</span> Concurrent hardware capabilities<a href=#navigator.hardwareconcurrency class=self-link></a></h4>

  <pre><code class='idl'><c- b>interface</c-> <c- b>mixin</c-> <dfn id='navigatorconcurrenthardware' data-dfn-type='interface'><c- g>NavigatorConcurrentHardware</c-></dfn> {
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-> <a href='#dom-navigator-hardwareconcurrency' id='navigator.hardwareconcurrency:dom-navigator-hardwareconcurrency'><c- g>hardwareConcurrency</c-></a>;
};</code></pre>

  <dl class=domintro><dt><code><var>self</var>.<a href=system-state.html#dom-navigator id=navigator.hardwareconcurrency:dom-navigator>navigator</a>.<a href=#dom-navigator-hardwareconcurrency id=dom-navigator-hardwareconcurrency-dev>hardwareConcurrency</a></code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Navigator/hardwareConcurrency title="The navigator.hardwareConcurrency read-only property returns the number of logical processors available to run threads on the user's computer.">Navigator/hardwareConcurrency</a><div class=support><span class="firefox yes"><span>Firefox</span><span>48+</span></span><span class="safari no"><span>Safari</span><span>10.1–11</span></span><span class="chrome yes"><span>Chrome</span><span>37+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>15+</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Navigator/hardwareConcurrency title="The navigator.hardwareConcurrency read-only property returns the number of logical processors available to run threads on the user's computer.">Navigator/hardwareConcurrency</a><div class=support><span class="firefox yes"><span>Firefox</span><span>48+</span></span><span class="safari no"><span>Safari</span><span>10.1–11</span></span><span class="chrome yes"><span>Chrome</span><span>37+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>15+</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><p>Returns the number of logical processors potentially available to the user agent.</dl>

  

  <p>
  <a id=navigator.hardwareconcurrency:tracking-vector title="There is a tracking vector here." href=https://infra.spec.whatwg.org/#tracking-vector class=tracking-vector data-x-internal=tracking-vector><img width=46 alt="(This is a tracking vector.)" crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/tracking-vector.svg height=64></a>
  The <dfn data-dfn-for=NavigatorConcurrentHardware id=dom-navigator-hardwareconcurrency data-dfn-type=attribute><code>navigator.hardwareConcurrency</code></dfn> attribute's
  getter must return a number between 1 and the number of logical processors potentially available
  to the user agent. If this cannot be determined, the getter must return 1.</p>

  <p>User agents should err toward exposing the number of logical processors available, using lower
  values only in cases where there are user-agent specific limits in place (such as a limitation
  on the number of <a href=#worker id=navigator.hardwareconcurrency:worker>workers</a> that can be created) or when the user agent
  desires to limit fingerprinting possibilities.</p>

  

  <h3 id=apis-available-to-workers><span class=secno>10.3</span> APIs available to workers<a href=#apis-available-to-workers class=self-link></a></h3>

  

  <h4 id=importing-scripts-and-libraries><span class=secno>10.3.1</span> Importing scripts and libraries<a href=#importing-scripts-and-libraries class=self-link></a></h4>

  <p>The <dfn data-dfn-for=WorkerGlobalScope id=dom-workerglobalscope-importscripts data-dfn-type=method><code>importScripts(...<var>urls</var>)</code></dfn>
  method steps are:</p>

  <ol><li><p>Let <var>urlStrings</var> be « ».<li>
    <p><a href=https://infra.spec.whatwg.org/#list-iterate id=importing-scripts-and-libraries:list-iterate data-x-internal=list-iterate>For each</a> <var>url</var> of <var>urls</var>:</p>

    <ol><li><p><a href=https://infra.spec.whatwg.org/#list-append id=importing-scripts-and-libraries:list-append data-x-internal=list-append>Append</a> the result of invoking the <a href=https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm id=importing-scripts-and-libraries:tt-getcompliantstring data-x-internal=tt-getcompliantstring>Get Trusted Type compliant string</a> algorithm with <code id=importing-scripts-and-libraries:tt-trustedscripturl><a data-x-internal=tt-trustedscripturl href=https://w3c.github.io/trusted-types/dist/spec/#trustedscripturl>TrustedScriptURL</a></code>, <a id=importing-scripts-and-libraries:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=importing-scripts-and-libraries:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global
     object</a>, <var>url</var>, "<code>WorkerGlobalScope importScripts</code>", and
     "<code>script</code>" to <var>urlStrings</var>.</ol>
   <li><p><a href=#import-scripts-into-worker-global-scope id=importing-scripts-and-libraries:import-scripts-into-worker-global-scope>Import scripts into worker global scope</a> given <a id=importing-scripts-and-libraries:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a> and
   <var>urlStrings</var>.</ol>

  <p>To <dfn id=import-scripts-into-worker-global-scope data-export="">import scripts into worker global scope</dfn>, given a
  <code id=importing-scripts-and-libraries:workerglobalscope><a href=#workerglobalscope>WorkerGlobalScope</a></code> object <var>worker global scope</var>, a <a id=importing-scripts-and-libraries:list href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of
  <a href=https://infra.spec.whatwg.org/#scalar-value-string id=importing-scripts-and-libraries:scalar-value-string data-x-internal=scalar-value-string>scalar value strings</a> <var>urls</var>, and an optional
  <a href=webappapis.html#fetching-scripts-perform-fetch id=importing-scripts-and-libraries:fetching-scripts-perform-fetch>perform the fetch hook</a>
  <var>performFetch</var>:</p>

  <ol><li><p>If <var>worker global scope</var>'s <a href=#concept-workerglobalscope-type id=importing-scripts-and-libraries:concept-workerglobalscope-type>type</a> is "<code>module</code>", throw a
   <code id=importing-scripts-and-libraries:typeerror><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code> exception.<li><p>Let <var>settings object</var> be the <a id=importing-scripts-and-libraries:current-settings-object href=webappapis.html#current-settings-object>current settings object</a>.<li><p>If <var>urls</var> is empty, return.<li><p>Let <var>urlRecords</var> be « ».<li>
    <p>For each <var>url</var> of <var>urls</var>:</p>

    <ol><li><p>Let <var>urlRecord</var> be the result of <a id=importing-scripts-and-libraries:encoding-parsing-a-url href=urls-and-fetching.html#encoding-parsing-a-url>encoding-parsing a URL</a> given
     <var>url</var>, relative to <var>settings object</var>.<li><p>If <var>urlRecord</var> is failure, then throw a <a id=importing-scripts-and-libraries:syntaxerror href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a>
     <code id=importing-scripts-and-libraries:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p><a href=https://infra.spec.whatwg.org/#list-append id=importing-scripts-and-libraries:list-append-2 data-x-internal=list-append>Append</a> <var>urlRecord</var> to
     <var>urlRecords</var>.</ol>
   <li>
    <p>For each <var>urlRecord</var> of <var>urlRecords</var>:</p>

    <ol><li><p><a id=importing-scripts-and-libraries:fetch-a-classic-worker-imported-script href=webappapis.html#fetch-a-classic-worker-imported-script>Fetch a classic worker-imported script</a> given <var>urlRecord</var> and
     <var>settings object</var>, passing along <var>performFetch</var> if provided. If this
     succeeds, let <var>script</var> be the result. Otherwise, rethrow the exception.<li>
      <p><a href=webappapis.html#run-a-classic-script id=importing-scripts-and-libraries:run-a-classic-script>Run the classic script</a> <var>script</var>, with
      <i>rethrow errors</i> set to true.</p>

      <p class=note><var>script</var> will run until it either returns, fails to parse, fails to
      catch an exception, or gets <a href=webappapis.html#abort-a-running-script id=importing-scripts-and-libraries:abort-a-running-script>prematurely aborted</a>
      by the <a href=#terminate-a-worker id=importing-scripts-and-libraries:terminate-a-worker>terminate a worker</a> algorithm defined above.</p>

      <p>If an exception was thrown or if the script was <a href=webappapis.html#abort-a-running-script id=importing-scripts-and-libraries:abort-a-running-script-2>prematurely aborted</a>, then abort all these steps, letting the exception or
      aborting continue to be processed by the calling <a href=webappapis.html#concept-script id=importing-scripts-and-libraries:concept-script>script</a>.</p>
     </ol>
   </ol>

  <p class=note><cite>Service Workers</cite> is an example of a specification that runs this
  algorithm with its own <a href=webappapis.html#fetching-scripts-perform-fetch id=importing-scripts-and-libraries:fetching-scripts-perform-fetch-2>perform the fetch
  hook</a>. <a href=references.html#refsSW>[SW]</a></p>

  


  <h4 id=the-workernavigator-object><span class=secno>10.3.2</span> The <code id=workernavigator-dev><a href=#workernavigator>WorkerNavigator</a></code> interface<a href=#the-workernavigator-object class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerNavigator title="The WorkerNavigator interface represents a subset of the Navigator interface allowed to be accessed from a Worker. Such an object is initialized for each worker and is available via the self.navigator property.">WorkerNavigator</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div>

  

  <p>The <dfn data-dfn-for=WorkerGlobalScope id=dom-worker-navigator data-dfn-type=attribute><code>navigator</code></dfn> attribute of the
  <code id=the-workernavigator-object:workerglobalscope><a href=#workerglobalscope>WorkerGlobalScope</a></code> interface must return an instance of the
  <code id=the-workernavigator-object:workernavigator><a href=#workernavigator>WorkerNavigator</a></code> interface, which represents the identity and state of the user agent
  (the client):</p>

  

  <pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Worker</c->]
<c- b>interface</c-> <dfn id='workernavigator' data-dfn-type='interface'><c- g>WorkerNavigator</c-></dfn> {};
<a href='#workernavigator' id='the-workernavigator-object:workernavigator-2'><c- n>WorkerNavigator</c-></a> <c- b>includes</c-> <a id='the-workernavigator-object:navigatorid' href='system-state.html#navigatorid'><c- n>NavigatorID</c-></a>;
<a href='#workernavigator' id='the-workernavigator-object:workernavigator-3'><c- n>WorkerNavigator</c-></a> <c- b>includes</c-> <a id='the-workernavigator-object:navigatorlanguage' href='system-state.html#navigatorlanguage'><c- n>NavigatorLanguage</c-></a>;
<a href='#workernavigator' id='the-workernavigator-object:workernavigator-4'><c- n>WorkerNavigator</c-></a> <c- b>includes</c-> <a id='the-workernavigator-object:navigatoronline' href='system-state.html#navigatoronline'><c- n>NavigatorOnLine</c-></a>;
<a href='#workernavigator' id='the-workernavigator-object:workernavigator-5'><c- n>WorkerNavigator</c-></a> <c- b>includes</c-> <a href='#navigatorconcurrenthardware' id='the-workernavigator-object:navigatorconcurrenthardware'><c- n>NavigatorConcurrentHardware</c-></a>;</code></pre>

  

  <h4 id=worker-locations><span class=secno>10.3.3</span> The <code id=workerlocation-dev><a href=#workerlocation>WorkerLocation</a></code> interface<a href=#worker-locations class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation title="The WorkerLocation interface defines the absolute location of the script executed by the Worker. Such an object is initialized for each worker and is available via the WorkerGlobalScope.location property obtained by calling self.location.">WorkerLocation</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/toString title="The toString() stringifier method of a WorkerLocation object returns a string containing the serialized URL for the worker's location. It is a synonym for WorkerLocation.href.">WorkerLocation/toString</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>15+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android yes"><span>WebView Android</span><span>37+</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>14+</span></span></div></div></div><pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Worker</c->]
<c- b>interface</c-> <dfn id='workerlocation' data-dfn-type='interface'><c- g>WorkerLocation</c-></dfn> {
  <c- b>stringifier</c-> <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-href' id='worker-locations:dom-workerlocation-href'><c- g>href</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-origin' id='worker-locations:dom-workerlocation-origin'><c- g>origin</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-protocol' id='worker-locations:dom-workerlocation-protocol'><c- g>protocol</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-host' id='worker-locations:dom-workerlocation-host'><c- g>host</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-hostname' id='worker-locations:dom-workerlocation-hostname'><c- g>hostname</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-port' id='worker-locations:dom-workerlocation-port'><c- g>port</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-pathname' id='worker-locations:dom-workerlocation-pathname'><c- g>pathname</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-search' id='worker-locations:dom-workerlocation-search'><c- g>search</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>USVString</c-> <a href='#dom-workerlocation-hash' id='worker-locations:dom-workerlocation-hash'><c- g>hash</c-></a>;
};</code></pre>

  

  

  <p>A <code id=worker-locations:workerlocation><a href=#workerlocation>WorkerLocation</a></code> object has an associated <dfn id=concept-workerlocation-workerglobalscope><code>WorkerGlobalScope</code> object</dfn> (a
  <code id=worker-locations:workerglobalscope><a href=#workerglobalscope>WorkerGlobalScope</a></code> object).

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/href title="The href property of a WorkerLocation object returns a string containing the serialized URL for the worker's location.">WorkerLocation/href</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-href data-dfn-type=attribute><code>href</code></dfn> getter steps are to return <a id=worker-locations:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
  <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope><code>WorkerGlobalScope</code>
  object</a>'s <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url>url</a>, <a href=https://url.spec.whatwg.org/#concept-url-serializer id=worker-locations:concept-url-serializer data-x-internal=concept-url-serializer>serialized</a>.</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/origin title="The origin property of a WorkerLocation object returns the worker's origin.">WorkerLocation/origin</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>29+</span></span><span class="safari yes"><span>Safari</span><span>10+</span></span><span class="chrome yes"><span>Chrome</span><span>38+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>14+</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-origin data-dfn-type=attribute><code>origin</code></dfn> getter steps are to return the <a href=browsers.html#ascii-serialisation-of-an-origin id=worker-locations:ascii-serialisation-of-an-origin>serialization</a> of <a id=worker-locations:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-2><code>WorkerGlobalScope</code> object</a>'s
  <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-2>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-origin id=worker-locations:concept-url-origin data-x-internal=concept-url-origin>origin</a>.</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/protocol title="The protocol property of a WorkerLocation object returns the protocol part of the worker's location.">WorkerLocation/protocol</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-protocol data-dfn-type=attribute><code>protocol</code></dfn> getter steps are to return
  <a id=worker-locations:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-3><code>WorkerGlobalScope</code> object</a>'s
  <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-3>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-scheme id=worker-locations:concept-url-scheme data-x-internal=concept-url-scheme>scheme</a>, followed by "<code>:</code>".</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/host title="The host property of a WorkerLocation object returns the host part of the worker's location.">WorkerLocation/host</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-host data-dfn-type=attribute><code>host</code></dfn> getter steps are:</p>

  <ol><li><p>Let <var>url</var> be <a id=worker-locations:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-4><code>WorkerGlobalScope</code> object</a>'s
   <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-4>url</a>.<li><p>If <var>url</var>'s <a href=https://url.spec.whatwg.org/#concept-url-host id=worker-locations:concept-url-host data-x-internal=concept-url-host>host</a> is null, return the empty
   string.<li><p>If <var>url</var>'s <a href=https://url.spec.whatwg.org/#concept-url-port id=worker-locations:concept-url-port data-x-internal=concept-url-port>port</a> is null, return
   <var>url</var>'s <a href=https://url.spec.whatwg.org/#concept-url-host id=worker-locations:concept-url-host-2 data-x-internal=concept-url-host>host</a>, <a href=https://url.spec.whatwg.org/#concept-host-serializer id=worker-locations:host-serializer data-x-internal=host-serializer>serialized</a>.<li><p>Return <var>url</var>'s <a href=https://url.spec.whatwg.org/#concept-url-host id=worker-locations:concept-url-host-3 data-x-internal=concept-url-host>host</a>, <a href=https://url.spec.whatwg.org/#concept-host-serializer id=worker-locations:host-serializer-2 data-x-internal=host-serializer>serialized</a>, followed by "<code>:</code>" and <var>url</var>'s <a href=https://url.spec.whatwg.org/#concept-url-port id=worker-locations:concept-url-port-2 data-x-internal=concept-url-port>port</a>, <a href=https://url.spec.whatwg.org/#serialize-an-integer id=worker-locations:serialize-an-integer data-x-internal=serialize-an-integer>serialized</a>.</ol>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/hostname title="The hostname property of a WorkerLocation object returns the hostname part of the worker's location.">WorkerLocation/hostname</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-hostname data-dfn-type=attribute><code>hostname</code></dfn> getter steps are:</p>

  <ol><li><p>Let <var>host</var> be <a id=worker-locations:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-5><code>WorkerGlobalScope</code> object</a>'s
   <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-5>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-host id=worker-locations:concept-url-host-4 data-x-internal=concept-url-host>host</a>.<li><p>If <var>host</var> is null, return the empty string.<li><p>Return <var>host</var>, <a href=https://url.spec.whatwg.org/#concept-host-serializer id=worker-locations:host-serializer-3 data-x-internal=host-serializer>serialized</a>.</ol>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/port title="The port property of a WorkerLocation object returns the port part of the worker's location.">WorkerLocation/port</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-port data-dfn-type=attribute><code>port</code></dfn> getter steps are:</p>

  <ol><li><p>Let <var>port</var> be <a id=worker-locations:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-6><code>WorkerGlobalScope</code> object</a>'s
   <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-6>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-port id=worker-locations:concept-url-port-3 data-x-internal=concept-url-port>port</a>.<li><p>If <var>port</var> is null, return the empty string.<li><p>Return <var>port</var>, <a href=https://url.spec.whatwg.org/#serialize-an-integer id=worker-locations:serialize-an-integer-2 data-x-internal=serialize-an-integer>serialized</a>.</ol>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/pathname title="The pathname property of a WorkerLocation object returns the pathname part of the worker's location.">WorkerLocation/pathname</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-pathname data-dfn-type=attribute><code>pathname</code></dfn> getter steps are to return the result
  of <a href=https://url.spec.whatwg.org/#url-path-serializer id=worker-locations:url-path-serializer data-x-internal=url-path-serializer>URL path serializing</a> <a id=worker-locations:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-7><code>WorkerGlobalScope</code> object</a>'s
  <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-7>url</a>.</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/search title="The search property of a WorkerLocation object returns the search part of the worker's location.">WorkerLocation/search</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-search data-dfn-type=attribute><code>search</code></dfn> getter steps are:</p>

  <ol><li><p>Let <var>query</var> be <a id=worker-locations:this-8 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-8><code>WorkerGlobalScope</code> object</a>'s
   <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-8>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-query id=worker-locations:concept-url-query data-x-internal=concept-url-query>query</a>.<li><p>If <var>query</var> is either null or the empty string, return the empty string.<li><p>Return "<code>?</code>", followed by <var>query</var>.</ol>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation/hash title="The hash property of a WorkerLocation object returns the hash part of the worker's location.">WorkerLocation/hash</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>3.5+</span></span><span class="safari yes"><span>Safari</span><span>4+</span></span><span class="chrome yes"><span>Chrome</span><span>4+</span></span><hr><span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>Internet Explorer</span><span>10+</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios yes"><span>Safari iOS</span><span>5+</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Android</span><span>12.1+</span></span></div></div></div><p>The <dfn data-dfn-for=WorkerLocation id=dom-workerlocation-hash data-dfn-type=attribute><code>hash</code></dfn> getter steps are:</p>

  <ol><li><p>Let <var>fragment</var> be <a id=worker-locations:this-9 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#concept-workerlocation-workerglobalscope id=worker-locations:concept-workerlocation-workerglobalscope-9><code>WorkerGlobalScope</code> object</a>'s
   <a href=#concept-workerglobalscope-url id=worker-locations:concept-workerglobalscope-url-9>url</a>'s <a href=https://url.spec.whatwg.org/#concept-url-fragment id=worker-locations:concept-url-fragment data-x-internal=concept-url-fragment>fragment</a>.<li><p>If <var>fragment</var> is either null or the empty string, return the empty string.<li><p>Return "<code>#</code>", followed by <var>fragment</var>.</ol>

  


  <nav><a href=web-messaging.html>← 9.3 Cross-document messaging</a> — <a href=index.html>Table of Contents</a> — <a href=worklets.html>11 Worklets →</a></nav>
